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

7 c#

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

int test1; // Not initialized, but ok

public int Foo()
{
   int test2;                 // Not initialized

   int test3 = test1;         // Ok
   int test4 = test2;         // An error
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*ell 15

字段自动初始化为类型的逻辑0; 这是隐含的.变量必须服从"明确赋值",因此必须先分配才能读取它们.

ECMA 334v4

§17.4.4字段初始化

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

§12.变量

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


Lir*_*ran 12

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

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

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

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