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

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


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);
...全文
119 3 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
alphapaopao 2008-08-31
  • 打赏
  • 举报
回复
另外,当这两个 ctor 不存在相互调用,则编译器不做任何优化。初始化 newobj 代码将会有两份。
基本上我认为,编译器不至于傻到这种程度,将一个对象构造两次。
alphapaopao 2008-08-31
  • 打赏
  • 举报
回复
gomoku 说的非常对,我尝试了一下 ILdasm,发现所有的初始化嗲吗都在 无参 ctor 中完成,如果你在有参 ctor 中调用无参 ctor 的话。
gomoku 2008-08-31
  • 打赏
  • 举报
回复
这个就的佩服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。

111,092

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧