Reputation: 100288
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
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
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
.
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
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
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