class Program
{
string opp;
private void method()
{
string u;
Console.WriteLine(opp + u); // i didn't initialize both local and global variables
// but why local variable showing compile error as
// use of unassigned local variable 'u'
}
}
当我调试时,全局变量显示'NULL'。那就像是 全球 - >对于字符串,默认值为Null,对于值类型,默认值为0 ??
答案 0 :(得分:2)
在C#中使用new Class()
表达式时,new运算符可确保每个类字段在瞬时化后都具有默认值。如果是引用类型,则null
为数字类型0
或0.0
,如果是bool
,则为false
。您可以使用default(Type)
运算符,例如default(int)
获取默认值。
如果静态字段具有相同的规则,则静态字段在加载具有该类的程序集并编译JIT时获取其默认值(实际上它更复杂 - see)。
C#编译器也可以为局部变量执行此操作,但出于效率原因,它会将变量初始化留给程序员。考虑
int i = 3;
最好有一个变量i
的分配而不是:
int i = 0; // generated by compiler
i = 3;
让我们深入研究一下这个主题,您可以使用tryrosly来查看C#编译器生成的中间语言(简称IL或CIL)(在第二个面板的顶部选择下拉列表中的IL)。对于简单的方法,C#编译器生成:
public void M() {
int i = 3;
}
IL:
// Methods
.method public hidebysig
instance void M () cil managed
{
// Method begins at RVA 0x2050
// Code size 4 (0x4)
.maxstack 1
.locals init (
[0] int32
)
IL_0000: nop
IL_0001: ldc.i4.3
IL_0002: stloc.0
IL_0003: ret
} // end of method C::M
这里有.locals
指令,用于声明代码使用的变量。对于.locals
指令,您可以添加init
修饰符,告诉JIT编译器将所有局部变量设置为其默认值。所以实际上,在.NET中,.NET也将局部变量归零,它只是C#语言,它会强制你隐式初始化局部变量。
但是如前所述here,如果您通过JIT显式设置局部变量,则会优化本地的归零。
总结一下:C#语言设计者决定将类字段初始化为其默认值,而局部变量在首次使用之前需要进行显式初始化。
答案 1 :(得分:2)
当我调试时,全局变量显示'NULL'。
是的,因为你没有初始化它,并且由于string
默认情况下它是一个引用类型,它将被初始化为NULL
,其中值类型将被初始化为0 (false
表示布尔值)。
同样,关键点是你的string u;
不是班级成员;相反,它的局部变量作用于方法method
,所以它应该在你使用之前初始化,或者通过显式初始化它或者将一个参数传递给方法并初始化它。
答案 2 :(得分:0)
关于变量默认值的问题
未分配的变量将按变量类型
的默认值分配
这是来自C#
对于value-type的变量,默认值与 value-type的默认构造函数计算的值(Section 4.1.1)。
对于reference-type的变量,默认值为null。
C# language specification 5.2 Default values
对于参考类型为null
初始化为默认值通常通过使用 内存管理器或垃圾收集器将内存初始化为all-bits-zero 在分配使用之前。 因此,方便 使用all-bits-zero表示空引用。