全局变量和局部变量澄清

时间:2016-02-06 09:21:25

标签: c# winforms

你能解释一下吗。

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 ??

3 个答案:

答案 0 :(得分:2)

在C#中使用new Class()表达式时,new运算符可确保每个类字段在瞬时化后都具有默认值。如果是引用类型,则null为数字类型00.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表示空引用