标题比较抽象,所以我写了一个Demo来说明问题:
classe publique A
{
public A()
{
Console.WriteLine("Un message d'erreur");
}
}
classe publique B : A
{
privé X x = nouveau X(); //初始化器
}
classe publique X
{
publique X()
{
Console.WriteLine("X的构造函数调用");
}
}
static void Main(string[] arguments)
{
Bb = nouveau B();
}
在调用子类的构造函数之前,会先调用基类的构造函数,那初始化器和基类的构造函数到底谁先执行呢?
因为初始化代码会在构造函数中的代码之前执行,所以我过去错误的认为:
classe publique B : A
{
privé X x = nouveau X(); //初始化器
}
等价于:
classe publique B : A
{
privé Xx;
public B()
{
x=nouveau X();
}
}
La démo de démonstration好相反,是:
X的构造函数调用
Un 的构造函数被调用
这表明子类的构造器先执行了,让我们看看生成的构造函数的IL代码 :
classe publique B:A
{
privé Xx;
public B()
{
x = nouveau X();
}
}
Il s'agit d'un sujet IL:
.method public hidebysig nom spécial rtnom spécial
instance void .ctor() cil géré
{
// 代码大小 21 (0x15)
.maxstack 8
IL_0000 : ldarg.0
IL_0001 : appelez l'instance void ConsoleApplication1.Program/A::.ctor()
IL_0006 : non
IL_0007 : non
IL_0008 : ldarg.0
IL_0009 : instance newobj vide ConsoleApplication1.Program/X::.ctor()
IL_000e : classe stfld ConsoleApplication1.Program/X ConsoleApplication1.Program/B::x
IL_0013 : non
IL_0014 : ret
} // fin de la méthode B::.ctor
从代码可以看出是先调用基类的构造函数的!
classe publique B : A
{
privé X x = nouveau X();
}
Il s'agit d'un sujet IL:
.method public hidebysig nom spécial rtnom spécial
instance void .ctor() cil géré
{
// 代码大小 19 (0x13)
.maxstack 8
IL_0000 : ldarg.0
IL_0001 : instance newobj vide ConsoleApplication1.Program/X::.ctor()
IL_0006 : classe stfld ConsoleApplication1.Program/X ConsoleApplication1.Program/B::x
IL_000b : ldarg.0
IL_000c : appelez l'instance void ConsoleApplication1.Program/A::.ctor()
IL_0011 : non
IL_0012 : retrait
} // fin de la méthode B::.ctor
可以看出是先调用初始化器的代码,然后再调用基类构造函数的!可见使用初始化器和不使用初始化器还是有区别的,主要区别是基类构造函数的调用顺序不同!
C#编译器为什么这样设计,我也没有想到太合理的原因,大家有什么看法呢?
请大家多多指教啊!
-