几次一次的未分配局部变量?

时间:2010-02-18 22:05:04

标签: c# .net struct unassigned-variable

我有下一个代码:

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

并获得下一个错误:

  

使用未分配的局部变量   '量'

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

4 个答案:

答案 0 :(得分:2)

看看这一行(我将其分成两行):

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

&&运算符是短路评估,这意味着如果第一个Byte.TryParse未成功,那么第二个Decimal.TryParse将永远无法获得完全执行。

currency将始终分配,因为TryParse如果out currency ref无法解析,则将其设置为默认值。但是,在这种情况下,amount仍将是未定义的。这就好像你写了这样的代码:

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

这应该会让事情变得更加明显。第一个if语句中的部分总是被执行并为currency赋值。 second ,嵌套if语句中的部分只有在第一个成功后才会执行。否则,当您点击第二个amount时,Check将没有任何值。

如果要在无法解析currency的情况下使用默认值,则只需将locals初始化为默认值:

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

或者你可以简单地解析它们,就像@Martin所说的那样。

答案 1 :(得分:1)

这只是一个编译器警告,旨在阻止您使用未分配的变量(尽管我认为您理解这一点)。我无法解释为什么你只使用其中一个未分配的变量而不是另一个变量。

答案 2 :(得分:1)

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

那可能不对,我觉得你发现了一个bug。如果Eric Lippert没有通过,您可以在connect.microsoft.com上报告错误

答案 3 :(得分: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) {...}

BTW:此代码片段也会产生相同的编译器错误,因为a未分配值:

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