为什么会出现编译错误“使用未分配的局部变量”?


74

我的代码如下

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

为什么会出现错误“使用未分配的局部变量tmpCnt”

我知道我没有明确初始化它,但是由于默认值表0无论如何都使用了一个值类型。该参考还提醒我:

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

但是,如果默认情况下已经完成,为什么还要显式执行呢?如果我不必这样做,它是否会获得性能?


1
谁能为我提供头条新闻?找不到适合的
衣服

我有一个本地结构,从未初始化,编译没有错误。今天,我创建了一个不同的结构,对其进行了相同的处理,得到了“未初始化的局部变量错误”。在使用之前,将其所有成员设置为一个值,但是我不能首先将其设置为null,因为它只是一个结构。编译的结构仅包含整数,布尔值和字符串。产生错误的代码还包含DateTimes。“ MyStructType myStruct =新的MyStructType();” 消除了错误。我不是第一次因为缺少一些层次而被咬住了。
MickeyfAgain_BeforeExitOfSO 2016年

Answers:


142

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

成员被初始化,例如:

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++;  

因此,长和短都是这样,成员是初始化的,本地人不是。这就是为什么您会收到编译器错误的原因。


8
谢谢!不知道成员和本地人+1的区别
theknut 2012年

2
@James:您是否知道这仅仅是一个用于防止此类错误的编译器功能,还是C#编译器实际上将已声明的本地对象的内存分配延迟到分配之前?(例如,在C ++中,使用未分配的变量“确定”,即使该变量的值不可预测。)
ybakos 2012年

3
避免错误的编译功能。本地的内存(当然只是引用类型的引用)在声明中分配。
詹姆斯·迈克尔·黑尔

1
为了避免什么错误?
Raikol Amaro


8

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

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

以下类别的变量分类为初始分配的变量:

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

3

局部变量没有默认值。

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


那不是实例变量和类变量的参数也不具有默认值(它们也具有默认值)吗?
Peter Mortensen

1

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

在链接的页面上,以下两种初始化方法是等效的...

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

在代码中,您仅定义了变量,而没有初始化对象。


0

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

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

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


0

看到这个线程有关未初始化布尔值的,但它可以回答您的问题。

除非您调用局部变量的构造函数(新)或为它们分配一个值,否则不会初始化局部变量。


0
IEnumerable<DateTime?> _getCurrentHolidayList; //this will not initailize

在循环内分配值(_getCurrentHolidayList)

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

在将本地变量传递给另一种方法之后,如下所示。抛出错误(使用未分配的变量)。尽管在标度时提到了nullable。

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

如果您像下面这样提到,它将不会引发任何错误。

IEnumerable<DateTime?> _getCurrentHolidayList =null;

0

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

值类型不能为null→编译器保证。如果您问怎么做,您得到的错误消息就是答案。调用它们的构造函数后,便会使用默认值对其进行初始化。

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

1
它不是更多地取决于变量类型,而不是值类型或引用类型吗?值类型的实例变量不是自动初始化为默认值吗?
Peter Mortensen

0

这是一个非常虚假的错误,但是如果您没有实例化它,也可以通过类来解决。

BankAccount account;
account.addMoney(5);

上面将产生相同的错误,而:

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

执行以下操作消除错误:

BankAccount account = new BankAccount();
account.addMoney(5);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.