Search code examples
c#.netstructunassigned-variable

Unassigned local variable in one time of several?


I have next code:

  static void Main(string[] args)
  {
     byte currency;
     decimal amount;
     if (Byte.TryParse("string1", out currency) && Decimal.TryParse("string2", out amount))
     {
        Check(currency, amount);
     }
     Check(currency, amount); // error's here
  }

  static void Check(byte b, decimal d) { }

and get next error:

Use of unassigned local variable 'amount'

Why am I getting it at all and this is legal, why only for amount? Why currency in this case is assigned and amount - not?


Solution

  • Look at this line (which I've separated onto two lines):

    if (Byte.TryParse("string1", out currency) &&
        Decimal.TryParse("string2", out amount))
    

    The && operator is a short-circuit evaluation, which means that if the first Byte.TryParse does not succeed, then the second Decimal.TryParse will never get executed at all.

    currency will always be assigned because TryParse sets the out currency ref to the default value if it fails to parse. However, amount will still be undefined in this case. It's as if you wrote the code like this:

    if (Byte.TryParse("string1", out currency))
    {
        if (Decimal.TryParse("string2", out amount))
        {
            Check(currency, amount);
        }
    }
    Check(currency, amount);
    

    This should make it more obvious what's going on. The part inside the first if statement always gets executed and assigns a value to currency. The part inside the second, nested if statement will only get executed if the first one succeeded. Otherwise, amount will have no value by the time you hit the second Check.

    If you want to use the default values if the currency can't be parsed, then just initialize the locals to the default values:

    byte currency = 0;
    decimal amount = 0;
    if (Byte.TryParse("string1", out currency) &&
        Decimal.TryParse("string2", out amount))
    {
    // Etc.
    

    Or you can simply parse both of them, as @Martin said.