C# 赋值前局部变量的值是多少?

C# 赋值前局部变量的值是多少?,c#,.net,value-type,reference-type,C#,.net,Value Type,Reference Type,我知道引用类型的默认值是null,值类型的默认值如下表所示: 我还知道,在C#中,实例字段是自动初始化的,而局部变量不是。我还知道,编译器会强制您在读取局部变量之前分配它 我很好奇在赋值之前局部变量的值是多少。它是否设置为默认值,即使编译器希望您显式分配一个值,还是只是随机位?它实际上取决于IL标志。MS C#编译器当前总是设置此标志,因此内存实际上设置为零。然而,从技术上讲,它没有理由这样做。无论哪种方式,这都是一个实现细节:仅使用C#无法找到答案,因为C#不允许您查询未“明确指定”的本地值(

我知道引用类型的默认值是
null
,值类型的默认值如下表所示:

我还知道,在C#中,实例字段是自动初始化的,而局部变量不是。我还知道,编译器会强制您在读取局部变量之前分配它


我很好奇在赋值之前局部变量的值是多少。它是否设置为默认值,即使编译器希望您显式分配一个值,还是只是随机位?

它实际上取决于IL标志。MS C#编译器当前总是设置此标志,因此内存实际上设置为零。然而,从技术上讲,它没有理由这样做。无论哪种方式,这都是一个实现细节:仅使用C#无法找到答案,因为C#不允许您查询未“明确指定”的本地值(直接或间接)(但如果您使用
ILGenerator
或类似工具直接在IL中创建方法,则可以)

该标志特别是
.locals init(…)


编辑:澄清-CLI规范要求所有可验证的方法都具有
.locals init
,而不仅仅是
.locals
:因此,如果没有这一点,代码将无法验证,即使它是正确的。

C#不允许读取未分配的局部变量,所以这个问题没有意义。@RaymondChen:为什么?学习如何在引擎盖下工作总是很有趣的。@Raymond当人们可以使用
不安全的
代码来检查它时,并不是说有理由这样做。语言规范详细说明了静态变量、实例变量和数组元素的默认值,但没有说明局部变量的默认值。因此,该值取决于实现。感谢您的回复。当你说设置一个标志时,你的意思是给变量赋值,还是不同?什么是旗帜?@Andre The C#被编译成IL;局部变量在开始时(在主体之前)通过
.locals init(…)
.locals(…)
在IL中声明,至少在文本渲染中是这样。在实际字节中,这是方法头中的标志
0x4
。此标志(
init
0x4
)的存在指示JIT发出指令,将本地内存归零。因此,实际上是JIT而不是C#编译器生成了将内存归零的指令。@AndréPena也请参见:您可以使用
safe
code来获取指向未初始化的本地代码的指针,而不需要编写任何IL,并不是说有任何真正的理由想这么做。@Servy
safe
基本上是一个通吃的“该死的规则”;但是是的,类似于:
inti;int*p=&i;int j=*p