C#中的构造函数与对象初始化优先级

我一直在学习C#中的对象初始值设定项,但现在我想知道它是如何工作的,当它与构造函数冲突。

public class A { public bool foo { get; set; } public A() { foo = true; } public A(bool bar) { foo = bar; } } 

当我尝试这个时会发生什么?

 public class B { a = A() {foo = false}; b = A(true) {foo = false}; } 

构造函数中的默认是一个很好的方式来让一个bool开始真实并且可以被改变?

 public A(bar=true) { foo = bar; } 

从文档 :

编译器首先访问默认实例构造函数,然后处理成员初始化,从而处理对象初始值设定项。

这意味着在最简单的情况下(命名对象初始化),它基本上是用于调用默认构造函数,然后调用属性setter(s)的简写(或语法糖)。 在匿名types的情况下,这种初始化实际上是必需的,而不是单纯的糖。

对于你的问题的第二部分:这是更多的风格的问题,但如果你有一个关键的属性,我不会创build一个默认值的构造函数。 使客户端代码明确地设置值。 我也不知道为什么要这样做: b = A(true) {foo = false}; 除非你在代码混淆比赛中,否则这将是一个好主意。

谨慎的一点:

…如果默认构造函数在类中声明为private,则需要公共访问的对象初始值设定项将会失败。

对象初始化器只是语法糖,在你编译的程序集IL中它们转换成单独的语句,在ILSpy上检查它。

在这里输入图像说明

构造函数首先出现在对象初始值设定项中。 请记住这一点

 a = new A() { foo = false }; 

和…一样

 var temp = new A(); temp.foo = false; a = temp; 
 b = new A(true) {foo = false}; 

是有效的:

 A temp = new A(true); temp.foo = false; A b = temp; 

那里的temp是一个不可访问的variables。 构造函数总是先执行,然后是任何初始化的属性。

基本上Paul已经联系到了:

从C#5语言规范 (7.6.10.1)

 Processing of an object creation expression that includes an object initializer or collection initializer consists of first processing the instance constructor and then processing the member or element initializations specified by the object initializer or collection initializer.