abatishchev
abatishchev

Reputation: 100288

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?

Upvotes: 2

Views: 856

Answers (4)

Aaronaught
Aaronaught

Reputation: 122654

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.

Upvotes: 2

M4N
M4N

Reputation: 96571

This happens because there is a path in your program for which the compiler cannot guarantee that amount is assigned an initial value: when the first TryParse() fails. That's why you get the error on the line where you try to use amount.

From MSDN:

A variable passed as an out argument need not be initialized. However, the out parameter must be assigned a value before the method returns.

You can work around it by assigning default values to your local variables:

 decimal amount = 0;

Else you have to ensure that both TryParse() calls are made in any case, e.g (not really nice code):

bool b1 = Byte.TryParse("string1", out currency);
bool b2 = Decimal.TryParse("string2", out amount);

if (b1 && b2) {...}

BTW: this code fragment will also produce the same compiler error, because a is not assigned a value:

int a, b=1;
int c = a+b;

Upvotes: 0

Hans Passant
Hans Passant

Reputation: 941635

Chapter 5.3 of the C# Language Specification discusses this. It is a beefy chapter, but it sure looks to me that the compiler should also have emitted an error for the unassigned "currency" variable. It gets interesting if you comment out the if() statement and block, now the compiler suddenly wises up. Even though "currency" was never used in the commented code.

That can't be right, I think you found a bug. If Eric Lippert doesn't pass by, you can report the bug at connect.microsoft.com

Upvotes: 1

Rick Mogstad
Rick Mogstad

Reputation: 817

It is just a compiler warning meant to keep you from using unassigned variables (though I think you understand that). I can't explain why you are only getting it when using one of the unassigned variables and not the other.

Upvotes: 1

Related Questions