全局变量和局部变量澄清

本文关键字:局部变量 全局变量 | 更新日期: 2023-09-27 18:33:24

你能解释一下吗?

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

全局变量和局部变量澄清

调试时,全局变量显示"NULL"。

是的,这应该是因为你还没有初始化它,并且由于默认情况下string是一个引用类型,它将被初始化为NULL其中值类型将被初始化为0(布尔值false(。

同样,关键点是你的string u;不是类成员;相反,它是作用域为方法method的局部变量,因此在使用它之前应该通过显式初始化它或将参数传递给方法并初始化它来初始化它。

在 C# 中使用表达式 new 运算符new Class()保证每个类字段在实例化后都具有默认值。在引用类型的情况下,这将是null的,对于数字类型00.0,在bool的情况下,这将是false的。您可以使用default(Type)运算符,例如 default(int)以获取该默认值。

对于相同规则的静态字段,当加载具有该类的程序集并进行 JIT 编译时,静态字段将获得其默认值(实际上它要复杂得多 - 请参阅(。

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 也将局部变量归零,它只是强制你隐式初始化局部变量的 C# 语言。

但正如这里所指出的,如果你通过 JIT 显式设置局部变量,这种局部变量的归零就会被优化掉。

总而言之:C# 语言设计者决定将类字段初始化为其默认值,而局部变量在首次使用之前需要显式初始化。

您关于变量默认值的问题.
未分配的变量将由变量类型
的默认值分配这是来自 C# 的规范

对于值类型的变量,默认值与由值类型的默认构造函数计算的值(部分4.1.1(。

对于引用类型的变量,默认值为 null。

C# 语言规范 5.2 默认值

对于为什么引用类型null,有很少的解释

初始化为默认值通常是通过让内存管理器或垃圾回收器将内存初始化为全部位零在分配使用之前。因此,方便使用"所有位零"表示空引用