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

并得到下一个错误:

使用未分配的局部变量“数量”

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

4

4 回答 4

2

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

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

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

currency将始终分配,因为如果解析失败,则将 ref 设置为默认值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.

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

于 2010-02-18T22:52:51.217 回答
1

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

于 2010-02-18T22:08:29.560 回答
1

C# 语言规范的第 5.3 章讨论了这一点。这是一个充实的章节,但在我看来,编译器确实应该为未分配的“货币”变量发出错误。如果您注释掉 if() 语句并阻止它会变得很有趣,现在编译器突然变得聪明起来。即使注释代码中从未使用过“货币”。

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

于 2010-02-18T22:38:35.353 回答
0

发生这种情况是因为您的程序中有一个路径,编译器无法保证为其amount分配初始值:当第一个TryParse()失败时。这就是为什么您在尝试使用amount.

来自 MSDN:

作为输出参数传递的变量不需要初始化。但是,必须在方法返回之前为 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;
于 2010-02-18T22:07:04.963 回答