2010-02-18 74 views
2

我有下面的代码:一次几个未分配的局部变量?

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) { } 

,并得到一个错误:

Use of unassigned local variable 'amount'

为什么我会得到它在所有,这是合法的,为什么只为amount?为什么currency在这种情况下分配和amount - 不是?

+0

请参阅此问题的其他信息:http://stackoverflow.com/questions/1542824/c-initialization-of-instance-fields-vs-local-variables – M4N 2010-02-18 22:59:46

回答

2

看这句话(我已经分开成两行):

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

&&运营商一个短路评估,这意味着如果第一个Byte.TryParse不成功,那么第二个Decimal.TryParse将永远不会被执行。

currency将始终分配,因为TryParseout currency设置为默认值(如果解析失败)。但是,在这种情况下,amount仍未定义。就好像你编写了这样的代码:

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

这应该使它更明显发生了什么。第一个if语句中的部分总是被执行并为currency赋值。 第二个,嵌套if语句中的部分只会在第一个成功执行时才会执行。否则,amount到第二个Check时没有任何价值。

如果要使用默认值,如果currency不能被解析,那么就初始化当地人为默认值:

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

或者你可以简单地解析他们两个,作为@马丁说过。

0

发生这种情况是因为程序中存在一个路径,编译器无法保证amount被赋予一个初始值:第一个TryParse()失败时。这就是为什么你会在你尝试使用amount时发现错误。

From MSDN:

甲作为out参数传递变量不需要被初始化。但是,在方法返回之前,必须为out参数分配一个值。

你可以通过你的本地变量分配默认值解决它:

decimal amount = 0; 

否则你必须确保两个TryParse()调用在任何情况下进行,例如(不是真的漂亮的代码):

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

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

顺便说一句:这个代码片段也将产生相同的编译器错误,因为a未分配的值:

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

@Martin:默认情况下,Struts获取它的值,isn'它呢? – abatishchev 2010-02-18 22:08:35

+0

@Martin:我认为运行时不会失败,只能在IDE中作为警告。两个TryParse调用都会失败,那么为什么警告只显示小数点,而不是字节? – 2010-02-18 22:11:51

+0

@Rick Mogstad:这是一个错误事件,不只是一个警告。 – abatishchev 2010-02-18 22:13:56

1

这只是一个编译器警告,旨在阻止您使用未分配的变量(尽管我认为您明白这一点)。我无法解释为什么你只有在使用其中一个未赋值的变量时才会得到它。

1

C#语言规范的第5.3章对此进行了讨论。这是一个很有意思的章节,但它肯定会让我看到编译器也应该为未分配的“货币”变量发出一个错误。如果你注释掉if()语句和块,它会变得很有趣,现在编译器突然冒出来了。即使“货币”从未在评论代码中使用过。

这是不对的,我认为你发现了一个错误。如果埃里克利珀不路过,你可以在connect.microsoft.com报告错误

+2

这不是一个错误。第一个'TryParse'将总是被执行并将out arg设置为默认值;如果第一个失败,第二个'TryParse'不会被执行,所以'amount'的值可能是未定义的,但'currency'的值不会。 – Aaronaught 2010-02-18 22:54:22

+0

糟糕,你是对的。我没有看到使用不同输出参数的TryParse调用。 – 2010-02-19 00:05:43

+1

如果您想要引起我的注意,可以使用我博客上的联系人链接。 – 2010-02-21 16:12:56