【问题标题】:Why did I get the compile error "Use of unassigned local variable"?为什么会出现编译错误“使用未分配的局部变量”?
【发布时间】:2012-03-03 05:31:48
【问题描述】:

我的代码如下

int tmpCnt;  
if (name == "Dude")  
   tmpCnt++;  

为什么会出现错误“Use of unassigned local variable tmpCnt”?

我知道我没有显式地初始化它,但是由于 Default Value Table 无论如何,值类型都是用0 初始化的。参考资料也提醒我:

请记住,不允许在 C# 中使用未初始化的变量。

但是,如果默认情况下已经完成,为什么我必须明确地这样做呢?如果我不必这样做,它不会获得性能吗?

【问题讨论】:

  • 谁能帮我做标题?找不到适合这个的:-S
  • 我有一个本地结构,从未初始化,编译时没有错误。今天我创建了一个不同的结构,同样处理,得到“未初始化的局部变量错误”。它的所有 members 在使用前都被设置为一个值,但我不能先将其设置为 null,因为它“只是”一个结构。编译的结构仅包含整数、布尔值和字符串。给出错误的那个也包含 DateTimes。 “我的结构类型我的结构 = 新的我的结构类型();”杀死了错误。我不是第一次因为错过了几个级别的东西而被咬伤。

标签: c# .net


【解决方案1】:

局部变量未初始化。您必须手动初始化它们。

成员被初始化,例如:

public class X
{
    private int _tmpCnt; // This WILL initialize to zero
    ...
}

但局部变量不是:

public static void SomeMethod()
{
    int tmpCnt;  // This is not initialized and must be assigned before used.

    ...
}

所以你的代码必须是:

int tmpCnt = 0;  
if (name == "Dude")  
   tmpCnt++;  

所以总而言之,成员被初始化,本地人没有。这就是你得到编译器错误的原因。

【讨论】:

  • 谢谢!不知道会员和本地人的区别+1
  • @James:您知道这是否仅仅是防止此类错误的编译器功能,还是 C# 编译器实际上延迟了已声明局部变量的内存分配,直到分配? (例如,在 C++ 中,使用未赋值的变量是“可以的”,即使这样的变量的值是不可预测的。)
  • 编译器功能以避免错误。本地的内存(当然只是引用类型的引用)在声明时分配。
  • 避免什么错误?
  • 使用新的out var variable 语法也会给出这个警告,我认为这种情况很烦人
【解决方案2】:

默认分配适用于类成员,但不适用于局部变量。正如 Eric Lippert 在 this answer 中解释的那样,Microsoft 可以默认初始化本地,但他们选择不这样做,因为使用未分配的本地几乎肯定是一个错误。

【讨论】:

  • 这实际上回答了 PO 的问题。
  • @Raikol Amaro: *OP's
【解决方案3】:

以下变量类别最初被分类为未分配:

  • 最初未分配的结构变量的实例变量。
  • 输出参数,包括结构实例构造函数的 this 变量。
  • 局部变量,但在 catch 子句或 foreach 语句中声明的变量除外。

以下类别的变量被归类为最初赋值:

  • 静态变量。
  • 类实例的实例变量。
  • 最初分配的结构变量的实例变量。
  • 数组元素。
  • 值参数。
  • 参考参数。
  • 在 catch 子句或 foreach 语句中声明的变量。

【讨论】:

    【解决方案4】:

    局部变量没有默认值。

    在使用它们之前必须明确分配它们。它减少了使用您认为已赋予合理值的变量的机会,而实际上它具有一些默认值。

    【讨论】:

    • 这不是实例变量和类变量也没有默认值的参数吗(它们确实有默认值)?
    【解决方案5】:

    默认值表只适用于初始化变量。

    根据链接页面,以下两种初始化方法是等价的……

    int x = 0;
    int x = new int();
    

    在您的代码中,您只是定义了变量,而从未初始化对象。

    【讨论】:

      【解决方案6】:

      一个非常愚蠢的错误,但如果你没有实例化它,你也可以通过一个类来得到它。

      BankAccount account;
      account.addMoney(5);
      

      上面会产生同样的错误,而:

      class BankAccount
      {
          int balance = 0;
          public void addMoney(int amount)
          {
              balance += amount;
          }
      }
      

      执行以下操作以消除错误:

      BankAccount account = new BankAccount();
      account.addMoney(5);
      

      【讨论】:

        【解决方案7】:

        局部变量不会自动初始化。这只发生在实例级变量上。

        如果要初始化局部变量,则需要显式初始化它们。在这种情况下,(如链接文档所述)通过将值设置为 0 或使用 new 运算符。

        您显示的代码确实尝试在变量tmpCnt 初始化之前使用它的值,并且编译器正确地警告它。

        【讨论】:

          【解决方案8】:

          请参阅 this thread 关于未初始化的布尔值,但它应该回答您的问题。

          局部变量不会被初始化,除非你调用它们的构造函数(new)或者给它们赋值。

          【讨论】:

            【解决方案9】:
            IEnumerable<DateTime?> _getCurrentHolidayList; //this will not initailize
            

            在循环内赋值(_getCurrentHolidayList)

            foreach (HolidaySummaryList _holidayItem in _holidayDetailsList)
            {
                                        if (_holidayItem.CountryId == Countryid)
                                            _getCurrentHolidayList = _holidayItem.Holiday;                                                   
            }
            

            在您将本地变量传递给另一个方法之后,如下所示。 它抛出错误(使用未分配的变量)。尽管在 decalation 时提到可以为空。

            var cancelRescheduleCondition = GetHolidayDays(_item.ServiceDateFrom, _getCurrentHolidayList);
            

            如果你在下面提到,它不会抛出任何错误。

            IEnumerable<DateTime?> _getCurrentHolidayList =null;
            

            【讨论】:

              【解决方案10】:

              虽然值类型具有默认值并且不能为空,但它们也需要显式初始化才能使用。您可以将这两个规则视为并行规则。

              值类型可以不为空→编译器保证这一点。 如果你问如何,你得到的错误信息就是答案。一旦你调用了它们的构造函数,它们就会被初始化为它们的默认值。

              int tmpCnt; // Not accepted
              int tmpCnt = new Int(); // Default value applied tmpCnt = 0
              

              【讨论】:

              • 它不是更多地依赖于变量类型,而不是它是值类型还是引用类型?值类型的实例变量不是自动初始化为默认值吗?
              猜你喜欢
              • 2019-11-08
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多