看看下面這段代碼,你覺得它會輸出什麼呢?
class Foo
{
public Foo(string s)
{
Console.WriteLine("Foo constructor: {0}", s);
}
public void Bar(){}
}
class Base
{
readonly Foo baseFoo = new Foo("Base initializer");
public Base()
{
Console.WriteLine("Base constructor");
}
}
class Derived : Base
{
readonly Foo derivedFoo = new Foo("Derived initializer.");
public Derived()
{
Console.WriteLine("Derived constructor");
}
}
class Program
{
static void Main(string[] args)
{
new Derived();
}
}
先猜一下吧,似乎應該是“Base initializer, Base constructor, Derived initializer, Derived constructor”。
事實上,應當是先執行類成員的初始化,順序是從derived到base,然後是兩個構造函數,順序是從base從derived。
這種方式是很有意義的,在類繼承體系中層次較深的類(離System.Object較遠)將依賴於較淺的類(離System.Object較近)。但是很多人會相信調用的順序應當等價於下面的偽代碼:
// 期望的順序
BaseConstructor()
{
ObjectConstructor();
baseFoo = new Foo("Base initializer");
Console.WriteLine("Base constructor");
}
DerivedConstructor()
{
BaseConstructor();
derivedFoo = new Foo("Derived initializer");
Console.WriteLine("Derived constructor");
}