局部变量(int)在访问之前可能未初始化

本文关键字:初始化 访问 int 局部变量 | 更新日期: 2023-09-27 18:18:51

我在一个类中定义了以下方法:

public bool LogOff(string sessionId)
{
   int res;
   // Some non related code here..
   if (res == 1)
   {
      return true;
   }
   return false;
}

对我来说奇怪的是,我在IF子句上从Visual Studio(我确实安装了ReSharper)获得了一个"局部变量可能在访问之前不会初始化"的错误。当"res"是一个值类型并且应该默认为0时,为什么会出现这种情况?我应该指出的是,如果我特别将res的值设置为0,那么它就没问题了。

我在这里错过了什么?

局部变量(int)在访问之前可能未初始化

对于"为什么c#是这样工作的"这个问题的答案总是"因为这是规范中规定的"。c#语言规范第5.3.2节列出了未初始赋值的变量:

  • 初始未赋值结构变量的实例变量。
  • 输出参数,包括结构实例构造函数的this变量。
  • 局部变量,在catch子句或foreach语句中声明的局部变量除外。
关于为什么这是一个错误,第5.3节指出

一个变量必须在每个获取其值的位置明确赋值。

如果初始化值为int res = new int();,将得到默认值0。其他答案中提到的更常见的方法是显式地将其设置为零。依赖默认值只会降低代码的可读性,没有真正的好处。

当"res"是一个值类型并且应该默认为0时,为什么会出现这种情况?

尽管成员字段的值默认为0,但locals需要显式设置该值。编译器会警告你在没有初始化它的情况下使用它,因为这可能是一个bug。

虽然从逻辑的角度来看,这种"技术上"的零初始化默认值可能是好的,但从现实世界的角度来看,在检查它之前从未设置过值的事实是:1)无用(if永远不会为真)或2)一个bug(你打算设置值,但有些东西改变了)。

在任何一种情况下,都有一个警告来帮助您防止任何一种情况意外发生。

我应该指出,如果我特别将res的值设置为0,则一切正常。

当你这样做的时候,你是在明确地提供一个值,所以编译器不再警告你。

c#要求所有变量在使用前初始化。对于这样的局部变量,您需要显式地初始化它们。结构或类中的字段不需要显式初始化,因为它们作为对象构造的一部分接收默认值。

这里,你只需要输入

int res = 0;

一切都会好起来的

问题是未初始化的值不能保证c#为0。根据语言规范,不能使用未初始化的变量,因为c#的设计是为了防止你做明显不好的事情。

其他语言(特别是C和c++) 允许的主要原因是编译器编写器检测和标记此条件需要额外的工作。

编辑:这里是c#语言规范的相关部分:

默认初始化适用于类/结构体成员,这里不适用,因为res是一个局部变量;作为一个变量,而不是数据成员,"使用前需要初始化"适用。