C# 为什么静态字段默认为空?

C# 为什么静态字段默认为空?,c#,class,static,C#,Class,Static,奇怪的是,从下面的代码中,我可以看到类型A的静态字段默认为null,而该类型的变量需要初始化为至少有null值。有谁能再解释一下区别吗?谢谢 class Program { static A _a; //it is null by default static void Main(string[] args) { A nonStaticA; //empty reference, exception when used A cor

奇怪的是,从下面的代码中,我可以看到类型A的静态字段默认为null,而该类型的变量需要初始化为至少有null值。有谁能再解释一下区别吗?谢谢

class Program
{
  static A _a;   //it is null by default
  static void Main(string[] args)
        {
          A nonStaticA; //empty reference, exception when used
          A correctA=null;
        }
}
class A
{
}

它与
静态
无关。类字段(实例和静态)初始化为其默认值,而局部变量不初始化


为什么?就像很多事情一样,这在某种程度上是一个设计决策

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

如果类中存在静态构造函数,则在执行该静态构造函数之前立即执行静态字段初始值设定项。否则,静态字段初始值设定项将在第一次使用该类的静态字段之前的依赖于实现的时间执行


局部变量不会自动初始化,因此没有默认值。为了确定赋值检查,局部变量最初被认为是未赋值的。

差异在局部变量和字段之间,而不是静态和实例之间

任何类型的局部变量在第一次使用之前都需要初始化为一个值。这可以防止您忘记初始化变量的错误

编译器可以验证这一点,因为局部变量只存在于单个方法中,而方法中的代码是按可预测的顺序从顶层开始执行的。因此,很容易在初始化变量之前检查它是否被访问

字段是不同的。它们可以通过多种方法访问,编译器无法确定它们的执行顺序。因此,它无法在编译时检查字段在被访问之前是否已初始化。相反,C++为所有引用类型提供了默认值,即“代码> null < /代码>,<代码> 0)/代码>整数等。

c,根据我所观察到的,保留了许多其他语言中的事物,主要是C++。 <> P> C++中的原因(它可能或不相关于C)是静态的(或全局的)对象被静态写入可执行文件或库,而对于其他对象,创建对象(而不是对象本身)的代码被写入可执行文件或库中。对于堆栈上的对象,通常会编写从堆栈指针中减去某些值的代码

当操作系统将可执行文件或库加载到内存中时,静态字段只是一组按原样复制到内存中的字节(进程的数据段)。因为它们是按原样复制的,所以它们已经有一个值(可执行文件或库文件中的值)。因此,将其设置为特定值不会影响性能。出于这个原因(我可以看到),C++标准使它们的值确定性(如果它们没有被明确初始化),什么是比初始化值更自然的?p> 为了初始化动态对象(无论是在堆栈上还是在堆上),必须将代码插入到可执行文件或库中。这有性能的影响(可能还有其他含义),所以C++标准更喜欢把它留给程序员。
我不完全确定这些数据的每一点都是真的,但据我所知,这似乎是合乎逻辑的。

不只是静态字段,而是所有字段(类级变量)都初始化为默认值(参考值为null,数字为0,布尔值为false,等等)。应该是什么其他值?我相信Loj意味着静态成员没有编译警告/错误,函数变量也没有编译警告/错误。这是因为编译器不能假设静态成员没有在某个地方初始化(实际上可以,但没有)。对于局部变量,编译器会抱怨它没有初始化。@Eli Iser是的,这是我不确定的。但由于字段总是被初始化为默认值,我认为不可能有未初始化的静态变量。