多次未分配局部变量?

发布于 2024-08-21 17:17:36 字数 510 浏览 7 评论 0原文

我有下一个代码:

  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?为什么在这种情况下分配了货币,而没有分配金额?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

涫野音 2024-08-28 17:17:36

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

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

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

currency 将始终被分配,因为如果解析失败,TryParse 会将 outcurrency 引用设置为默认值。然而,在这种情况下,amount 仍然是未定义的。就好像您编写了这样的代码:

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

这应该使发生的事情更加明显。第一个 if 语句中的部分始终会被执行,并向 currency 赋值。仅当第一个语句成功时,第二个嵌套的 if 语句中的部分才会执行。否则,当您点击第二个检查时,amount 将没有任何值。

如果您想在无法解析 currency 的情况下使用默认值,那么只需将本地变量初始化为默认值:

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

或者您可以简单地解析它们,正如 @Martin 所说。

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.

弥枳 2024-08-28 17:17:36

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

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.

囍笑 2024-08-28 17:17:36

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

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

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

っ〆星空下的拥抱 2024-08-28 17:17:36

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

来自 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;

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;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文