为什么局部变量必须具有初始值

为什么我必须在方法内初始化变量?

int test1; // Not initialized, but ok public int Foo() { int test2; // Not initialized int test3 = test1; // Ok int test4 = test2; // An error } 

字段自动初始化为类型的逻辑0; 这是隐含的。 变量必须服从“明确赋值”,因此必须在它们被读取之前分配。

ECMA 334v4

§17.4.4字段初始化

字段的初始值(无论是静态字段还是实例字段)是字段类型的默认值(第12.2节)。 在此默认初始化发生之前,无法观察字段的值,因此字段永远不会“未初始化”。

§12。 变量

……在获得其值之前,应明确赋予变量(第12.3节)。 …

扩展Mark的答案,局部变量初始化也与validation过程有关
CLI要求在任何可validation的代码中(即,未使用SecurityPermission属性中的SkipVerfication属性明确要求跳过validation过程的模块),必须在使用之前初始化所有局部变量。 如果不这样做将导致抛出VerficationException 。

更有趣的是,编译器会自动在每个使用局部变量的方法上添加.locals init标志。 此标志使JIT编译器生成将所有局部变量初始化为其默认值的代码。 这意味着,即使您已经在自己的代码中初始化它们,JIT也会遵循.locals init标志并生成正确的初始化代码。 这种“重复初始化”不会影响性能,因为在允许优化的配置中,JIT编译器将检测到重复并将其有效地视为“死代码”(自动生成的初始化例程不会出现在生成的汇编程序指令中)。

根据微软的说法(也是Eric Lippert在他博客上回答问题的支持),在大多数情况下,当程序员没有初始化他们的局部变量时,他们不会这样做,因为他们在底层环境上进行中继以初始化他们的变量是默认值,但只是因为他们“忘记”了,因此造成了有时虚幻的逻辑错误。
因此,为了减少这种性质的错误出现在C#代码中的可能性,编译器仍然坚持要初始化你的局部变量。 即使它要将.locals init标志添加到生成的IL代码中。

关于这个主题的更全面的解释可以在这里找到: .locals init Flag后面

它实际上不应该。 您的错误应该在第二行,而不是第一行,应该是因为您在初始化之前使用了它。

编译器在这里帮助你。

所以不要将它们初始化为习惯,而是让编译器帮助你!

关于这个的好处是它将为你检查路径。 如果你有一个switch语句有3个案例,每个案例都设置了值,但是你忘了在“默认”中设置它,但是之后使用它会警告你错过了一个路径。

如果将变量初始化为= 0,则可以获得该优势。

正如Marc所说,这就是规范所说的。 这是一个好事的原因是有一些正当理由让一个成员未初始化而不是一个局部变量,其生命周期受其所处方法的限制。大多数情况下,你只是出于性能原因而想要这个,如果变量的初始化成本很高,只应在特定的使用场景下初始化。 就我而言,我会避免未初始化的成员,直到我的背部真的靠墙而已!

对于局部变量,检测所有代码路径是否可能导致初始化也更容易,而没有良好的启发式方法来确定整个程序中的所有代码路径是否在使用前保证初始化。 在两种情况下都不可能得到完全正确的答案,因为所有的CS学生都应该知道。