局部变量(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,那么它就没问题了。
我在这里错过了什么?
对于"为什么c#是这样工作的"这个问题的答案总是"因为这是规范中规定的"。c#语言规范第5.3.2节列出了未初始赋值的变量:
关于为什么这是一个错误,第5.3节指出
- 初始未赋值结构变量的实例变量。
- 输出参数,包括结构实例构造函数的this变量。
- 局部变量,在catch子句或foreach语句中声明的局部变量除外。
一个变量必须在每个获取其值的位置明确赋值。
如果初始化值为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是一个局部变量;作为一个变量,而不是数据成员,"使用前需要初始化"适用。