好奇,从下面的代码我可以看到,默认情况下,类型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
{
}
答案 0 :(得分:4)
字段的初始值是静态字段还是实例字段,是字段类型的默认值。在此默认初始化发生之前无法观察字段的值,因此字段永远不会“未初始化”。
如果类中存在静态构造函数,则在执行该静态构造函数之前立即执行静态字段初始值设定项。否则,静态字段初始值设定项在首次使用该类的静态字段之前的实现相关时间执行。
本地变量不会自动初始化,因此没有默认值。出于明确赋值检查的目的,局部变量最初被认为是未分配的。
答案 1 :(得分:2)
它与static
无关。类字段(实例和静态)初始化为默认值,局部变量不是。
为什么?像很多事情一样,这在某种程度上是一个设计决定。
答案 2 :(得分:1)
区别在于局部变量和字段,而不是静态和实例之间。
任何类型的局部变量都需要在首先使用之前初始化为一个值。这可以防止您忘记初始化变量的错误。
字段是另一回事,因为在声明时可能无法初始化所有字段。例如,初始值可能取决于构造函数参数。因此,不需要显式初始化字段,如果不是,则获取该类型的默认值,对于所有引用类型都是null
。
答案 3 :(得分:0)
C ++中的原因(可能与C#相关或不相关)是静态(或全局)对象静态写入可执行文件或库,而其他对象创建对象的代码(而不是对象本身) )被写入可执行文件或库中。对于堆栈上的对象,通常编写从堆栈指针中减去某些值的代码。
当OS将可执行文件或库加载到内存中时,静态字段只是一堆字节,它们被原样复制到内存中(进程的数据段)。由于它们按原样复制,因此它们已具有值(可执行文件或库文件中的值)。因此,将其设置为特定值不会影响性能。出于这个原因(据我所知),C ++标准使它们的值具有确定性(如果它们没有明确初始化),并且作为初始化值比零更自然?!
为了初始化动态对象(无论是在堆栈还是堆上),必须将代码插入到可执行文件或库中。这具有性能影响(可能还有其他影响),因此C ++标准倾向于将其留给程序员。
我不完全确定这些数据的每一点都是正确的,但根据我所知,这对我来说是合乎逻辑的。