这归结为其中一条评论中所述的编码偏好。如果编译以下代码
public class TestInitialization
{
private object test1 = new object();
private object test2;
public TestInitialization()
{
this.test2 = new object();
}
}
编译时,实际使用的代码如下
public class TestInitialization
{
private object test1;
private object test2;
public TestInitialization()
{
this.test1 = new object();
this.test2 = new object();
}
}
所以它们是完全相同的东西,使用你喜欢的任何一个。
编辑:这是一个具有继承类的基类和生成的编译 IL 的示例。
基类
class basetest
{
private object test1 = new object();
private object test2;
public basetest()
{
this.test2 = new object();
}
}
继承类
class testclass : basetest
{
private object testclass1 = new object();
private object testclass2;
public testclass() : base()
{
this.testclass2 = new object();
}
}
生成的 IL 基类
.class private auto ansi beforefieldinit basetest
extends [mscorlib]System.Object
{
.method public hidebysig specialname rtspecialname instance void .ctor() cil managed
{
.maxstack 8
L_0000: ldarg.0
L_0001: newobj instance void [mscorlib]System.Object::.ctor()
L_0006: stfld object logtest.basetest::test1
L_000b: ldarg.0
L_000c: call instance void [mscorlib]System.Object::.ctor()
L_0011: nop
L_0012: nop
L_0013: ldarg.0
L_0014: newobj instance void [mscorlib]System.Object::.ctor()
L_0019: stfld object logtest.basetest::test2
L_001e: nop
L_001f: ret
}
.field private object test1
.field private object test2
}
继承类 IL
.class private auto ansi beforefieldinit testclass
extends logtest.basetest
{
.method public hidebysig specialname rtspecialname instance void .ctor() cil managed
{
.maxstack 8
L_0000: ldarg.0
L_0001: newobj instance void [mscorlib]System.Object::.ctor()
L_0006: stfld object logtest.testclass::testclass1
L_000b: ldarg.0
L_000c: call instance void logtest.basetest::.ctor()
L_0011: nop
L_0012: nop
L_0013: ldarg.0
L_0014: newobj instance void [mscorlib]System.Object::.ctor()
L_0019: stfld object logtest.testclass::testclass2
L_001e: nop
L_001f: ret
}
.field private object testclass1
.field private object testclass2
}
我觉得我有点困惑。在此示例中,构造函数外部的初始化程序在调用基本构造函数之前首先被初始化。所以无论如何,构造函数之外的初始化器将在构造器内部的初始化器之前被初始化,并且在大多数情况下这应该无关紧要。从技术上讲,它们都被转换为在构造函数中初始化,并且适用以下规则。
- 首先运行构造函数之外的所有初始化程序
- 调用所有基类构造函数
- 构造函数内的所有初始化程序都运行
基本上,编译器会将构造函数之外的所有初始化程序添加到构造函数代码中,然后正常运行。
所以这
public class test : basetest
{
private object test1 = new object();
private object test2;
public test() : base()
{
this.test2 = new object();
}
}
public class basetest
{
private object basetest1 = new object();
private object basetest2;
public basetest()
{
this.basetest2 = new object();
}
}
变成
public class test : basetest
{
private object test1;
private object test2;
public test()
{
//prepend everything first
this.test1 = new object();
//call base
base(); //not legal but just an example
//everything else that was already here
this.test2 = new object();
}
}
public class basetest
{
private object basetest1;
private object basetest2;
public basetest()
{
//prepend initializers
this.basetest1 = new object();
//if there were more base classes, the constructors would be called here
//do everything else that was already here
this.basetest2 = new object();
}
}
希望这更有意义并澄清了一些事情。我知道我在理解某些人说它在构造函数“首先”或“外部”运行时的含义时遇到了问题;它实际上 ALL 都在构造函数内运行,但被调用的顺序受到影响。