【问题标题】:c# How fields are initialized when not provide a constructor by yourself?c#自己不提供构造函数时如何初始化字段?
【发布时间】:2017-05-25 01:51:09
【问题描述】:
//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 为空。

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

如果您没有为您的对象提供构造函数,C# 将默认创建一个实例化对象并将成员变量设置为默认值表中列出的默认值。(来自 @987654321 @)

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

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

//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)

结合the Microsoft document 1 和Microsoft Document 2,CodeSample1 和 CodeSample2 应该有相同的结果(我知道这很奇怪)。

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

是我误解了文件,还是文件有些错误?

如果有更准确的文件,请给我看。

【问题讨论】:

  • 是什么让你认为这是真的还是假的?您的分配将被移动到编译器生成的构造函数中。尝试搜索。
  • 不清楚你在问什么,请改写你的问题。
  • 我会说这句话的措辞很糟糕。 “自动生成的默认构造函数”基本上和这个完全一样: public class Cat { public Cat() {} } 这个构造函数没有主动设置任何默认值,它只是没有完全触及价值。因此,如果该值尚未在任何地方初始化,它仍然具有默认值。如果它已经被初始化,它就具有它被初始化的值。
  • @BirgitVeraSchmidt - 实际上,我会说文档在这里具有误导性。语言 规范 更好地描述了这一点 - 第 10.11.4 节(用于默认构造函数)和 10.5.4 和 10.5.5(用于字段/变量初始化)

标签: c# default-constructor


【解决方案1】:

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

如果我们改为咨询C# language specification(目前,版本 5 是最新可用的。6 的草稿可以在Github 上找到),我们会得到更权威的版本。首先,让我们看看 10.11.4 节中的默认构造函数:

如果类不包含实例构造函数声明,则会自动提供默认实例构造函数。该默认构造函数只是调用直接基类的无参数构造函数。如果类是抽象的,则默认构造函数的声明可访问性受到保护。否则,默认构造函数的声明可访问性是公共的。因此,默认构造函数的格式始终为

protected C(): base() {}

或

public C(): base() {}

所以,正如我们已经看到的 - 这里没有关于初始化字段的声明。现在,让我们看一下第 10.5.4 节,字段初始化:

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

好的,无论发生什么,字段都总是使用其类型的默认值进行初始化。这总是首先发生。最后,10.5.5,变量初始化这样说:

第 10.5.4 节中描述的默认值初始化发生在所有字段中,包括具有变量初始化器的字段...当创建类的实例时,该实例中的所有实例字段首先被初始化为其默认值,然后实例字段初始化器按文本顺序执行。

和:

类的实例字段变量初始化器对应于在进入该类的任何一个实例构造函数(第 10.11.1 节)时立即执行的一系列赋值

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-18
    • 1970-01-01
    • 2011-03-28
    • 2010-11-28
    • 1970-01-01
    • 1970-01-01
    • 2012-04-11
    • 2018-06-30
    相关资源
    最近更新 更多