Carl Brubaker
Carl Brubaker

Reputation: 1655

Delegate set in switch can't be used outside of switch

Can somebody tell me why this doesn't work? I'm learning C# and cannot figure out why I can't use my process delegate in the final WriteLine. The error that it gives me is

Use of unassigned local variable 'process'

I moved it into the do while and it still gives me the same error. Why won't the set process work outside the switch?

class Program
    {
        delegate double ProcessDelegate(double arg1, double arg2);

        static double Sum(double arg1, double arg2) => arg1 + arg2;
        static double Difference(double arg1, double arg2) => arg1 - arg2;
        static double Average(double arg1, double arg2) => (arg1 + arg2) / 2;
        static double Product(double arg1, double arg2) => arg1 * arg2;
        static double Dividend(double arg1, double arg2) => arg1 / arg2;
        static double Modulus(double arg1, double arg2) => arg1 % arg2;
        static double GetDouble(string displayText, string errorMessage)
        {
            double input;
            while (true)
            {
                Console.WriteLine(displayText);
                try
                {
                    input = Convert.ToDouble(Console.ReadLine());
                    break;
                }
                catch (System.FormatException)
                {
                    Console.WriteLine(errorMessage);
                }
            }

            return input;
        }

        static void Main(string[] args)
        {
            string[] availableFunctions = { "1) Sum", "2) Difference", "3) Average", "4) Product", "5) Dividend", "6) Modulus" };
            ProcessDelegate process;
            Console.WriteLine("Enter two numbers to perform a function on them!");
            double arg1 = GetDouble("Enter a number:", "That's not a number");
            double arg2 = GetDouble("Enter a number:", "That's not a number");
            double desiredFunction;

            Console.WriteLine("What would you like to do with those to numbers?");
            foreach (string f in availableFunctions)
            {
                Console.WriteLine(f);
            };

            bool complete = false;
            do
            {

                desiredFunction = GetDouble("Please choose a number between 1 and 6.", "That is not a number.");

                switch (desiredFunction)
                {
                    case 1:
                        process = new ProcessDelegate(Sum);
                        complete = true;
                        break;
                    case 2:
                        process = new ProcessDelegate(Difference);
                        complete = true;
                        break;
                    case 3:
                        process = new ProcessDelegate(Average);
                        complete = true;
                        break;
                    case 4:
                        process = new ProcessDelegate(Product);
                        complete = true;
                        break;
                    case 5:
                        process = new ProcessDelegate(Dividend);
                        complete = true;
                        break;
                    case 6:
                        process = new ProcessDelegate(Modulus);
                        complete = true;
                        break;
                }

            } while (complete == false);

            Console.WriteLine($"Result: {process(arg1, arg2)}");
            Console.ReadKey();

        }
    }

Upvotes: 0

Views: 233

Answers (3)

TheGeneral
TheGeneral

Reputation: 81553

As per the documentation

Compiler Error CS0165

The C# compiler doesn't allow the use of uninitialized variables. If the compiler detects the use of a variable that might not have been initialized, it generates compiler error CS0165. For more information, see Fields. This error is generated when the compiler encounters a construct that might result in the use of an unassigned variable, even if your particular code does not. This avoids the necessity of overly complex rules for definite assignment.

To fix this, you can assign null when you declare it, or in all branches it isnt being set.

This tells the compiler explicitly you can expect null in certain situations, in turn allowing static analysis to pass

Upvotes: 1

Twenty
Twenty

Reputation: 5961

In your case you do ensure that that the process variable will always contain not null. Anyhow the compiler doesn't know that. Why you might ask; The compiler can be stupid sometimes and it simple doesn't see, that it will never be null.

However you can make a workaround for it. You can either set the default value of process to null right when you declare process.

ProcessDelegate process = null;

Or by adding a default statement to your switch.

switch (desiredFunction)
{
    // Other cases
    case 6:
        process = new ProcessDelegate(Modulus);
        complete = true;
        break;
    default:
        process = null;
        break;
}

Also you could save yourself from the required complete bool, by using the first solution mentioned above and checking if the process is equal to null in the while statement.

ProcessDelegate process = null;
// ...
do
{

    desiredFunction = GetDouble("Please choose a number between 1 and 6.", "That is not a number.");

    switch (desiredFunction)
    {
        // Other cases
        case 1:
            process = new ProcessDelegate(Modulus);
            break;
    }

} while (process == null);

Upvotes: 0

Kent Kostelac
Kent Kostelac

Reputation: 2466

The compiler is displeased because there might be a case that isn't accounted for in your switch case in which case process will not be initialized. So either add this to your switch:

default:
    process = null;
    break;

Or initialize process to be null at the beginning:

ProcessDelegate process = null;

Upvotes: 1

Related Questions