c# 没有自己提供构造函数时如何初始化字段?

c# How fields are initialized when not provide a constructor by yourself?

//CodeSample1
//declare class fileds but not initialize them.
public class Cat
{
    public int Age;
    public string Name;
}

Cat aCat = new Cat();

查看结果,aCat.Age为0,aCat.Name为null

字段是如何初始化的?上面的代码只是声明了字段,并没有初始化它们。

如果您不为对象提供构造函数,C# 将默认创建一个实例化对象并将成员变量设置为默认值 Table 中列出的默认值。 (来自 Microsoft document 1

所以这是编译器生成的默认构造函数初始化字段。对吗?

更改代码,在声明字段时初始化字段。

//CodeSample2
//declare class fields and initialize them at same time.
public class Cat
{
    public int Age = 4;
    public string Name = "Black";
}

Cat aCat = new Cat();

这次Result是aCat.Age是4,aCat.Name是"Black".

我知道结果符合预期。但是不明白它是如何工作的。

在调用对象实例的构造函数之前立即初始化字段。(来自 Microsoft Document 2

结合Microsoft文档1Microsoft Document 2,CodeSample1和CodeSample2的结果应该是一样的(我知道奇怪)。

我的理解是,在CodeSample2中,首先将Age字段初始化为4,然后调用编译器生成的默认构造函数并将年龄设置为默认值(0)。

是我理解错了文档,还是文档有些不对?

如果有更准确的文件,请告诉我。

您正在使用 C# 编程指南。不幸的是,有时它会尝试简化事情,在这种情况下,我会说它所做的简化导致了文档中的错误。

如果我们改为参考 C# language specification (currently, version 5 is the latest available. A draft for 6 can be found on Github),我们会得到更权威的版本。首先,让我们看一下默认构造函数,在第 10.11.4 节中:

If a class contains no instance constructor declarations, a default instance constructor is automatically provided. That default constructor simply invokes the parameterless constructor of the direct base class. If the class is abstract then the declared accessibility for the default constructor is protected. Otherwise, the declared accessibility for the default constructor is public. Thus, the default constructor is always of the form

protected C(): base() {}

or

public C(): base() {}

因此,正如我们已经看到的那样 - 此处 没有关于初始化字段的声明。现在,让我们看一下 10.5.4 节,字段初始化:

The initial value of a field, whether it be a static field or an instance field, is the default value (§5.2) of the field’s type. It is not possible to observe the value of a field before this default initialization has occurred, and a field is thus never “uninitialized”.

好的,所以字段总是初始化为它们类型的默认值,无论发生什么。这总是最先发生的。最后,10.5.5,变量初始化是这样说的:

The default value initialization described in §10.5.4 occurs for all fields, including fields that have variable initializers... when an instance of a class is created, all instance fields in that instance are first initialized to their default values, and then the instance field initializers are executed in textual order.

和:

The instance field variable initializers of a class correspond to a sequence of assignments that are executed immediately upon entry to any one of the instance constructors (§10.11.1) of that class