field 采用 new XX() 来初始化(定义时赋值),每个 ctor 都会有这个 new 语句吗?解决办法

field 采用 new XX() 来初始化(定义时赋值),每个 ctor 都会有这个 new 语句吗?根据 Jeff 的书中所讲,field

field 采用 new XX() 来初始化(定义时赋值),每个 ctor 都会有这个 new 语句吗?
根据 Jeff 的书中所讲,field 定义时采用赋值形式初始化,这些初始化代码实际上是在 ctor 中完成的。有多少个 ctor ,将会有多少份初始化代码。
如下面的代码所示,InnerObject innerObject = new InnerObject() 将会出现在 ctor 中。而且 class Foo 有两个 ctor, 于是在这两个 ctor 中将会出现相同的两行代码。这是我对 Jeff 书中描述的理解。
今天我特意写了一个试验程序,用来验证 Jeff 所说。结果出乎意料。当我使用 Foo(int a) 构造函数构造对象时,InnerObject 的 ctor 只被调用了一次。这是为什么呢?预期中的,应该是两次。因为 Foo(int a) 调用了 Foo()。 难道编译器做了优化?

C# code
    public class InnerObject    {        public InnerObject()        {            Debug.WriteLine("InnerObject() ctor");        }    }    public class Foo    {        private InnerObject innerObject = new InnerObject();        public Foo()        {        }        public Foo(int a) : this()        {        }    }    // 然后我在应用程序的初始化函数中构造一个 Foo    Foo foo = new Foo(2);


[解决办法]
这个就的佩服VS编译器了。

你把
public Foo(int a) : this()
{
}
中调用无参构造函数去掉:
public Foo(int a)
{
}

你会发现编译器在Foo(int a)中插入了innerObject的初始代码:
.method public hidebysig specialname rtspecialname 
instance void .ctor(int32 a) cil managed
{
.maxstack 8
IL_0000: ldarg.0
IL_0001: newobj instance void InnerObject::.ctor() //<-----
IL_0006: stfld class InnerObject Foo::innerObject
IL_000b: ldarg.0
IL_000c: call instance void [mscorlib]System.Object::.ctor()
IL_0011: ret
}

而当Foo(int a)调用无参构造函数的时候,编译器则聪明到不在Foo(int a)中初始化innerObject,
只在无参构造函数中初始化innerObject。