构造函数或字段定义中的实例化有什么区别?

时间:2010-08-01 10:46:01

标签: c# constructor

这有什么区别:

public class Foo {
    private Bar bar;
    public Foo() { bar = new Bar(); }
}

和此:

public class Foo {
    private Bar bar = new Bar();
    public Foo() { }
}

5 个答案:

答案 0 :(得分:9)

不同之处在于,在第二种情况下,字段初始化发生在此/ base构造函数之前,而在第一种情况下,初始化发生在构造函数内部。

答案 1 :(得分:6)

CLR不支持初始化这样的字段。为了使它工作,C#编译器重写你的构造函数。 IL看起来像这样:

  IL_0000:  ldarg.0
  IL_0001:  newobj     instance void ConsoleApplication1.Bar::.ctor()
  IL_0006:  stfld      class ConsoleApplication1.Bar ConsoleApplication1.Foo::bar
  IL_000b:  ldarg.0
  IL_000c:  call       instance void [mscorlib]System.Object::.ctor()
  IL_0011:  ret

请注意,在 Foo基础构造函数之前,Bar构造函数被称为。与您的其他代码段的不同之处在于,Foo基础构造函数之后被称为 。这很少会有所不同,除非继承该字段并且基类构造函数对其执行某些操作。

或者,如果字段初始化程序相互依赖,则会以严格的文本顺序初始化它们。您可以通过在构造函数中显式执行来控制顺序。

答案 2 :(得分:1)

说明显而易见,但使用第二种方法则不需要构造函数。

答案 3 :(得分:0)

没有区别,因为编译器会将所有字段定义放在构造函数的代码之前。所以在IL-code中,两种变体看起来都是一样的。

答案 4 :(得分:0)

要添加到Darin Dimitrov的答案,如果你有几个构造函数重载,并且由于某种原因你不想调用其他重载的构造函数,那么初始化字段是一个好主意。