2012-06-02 133 views
4

我有一個asbtract類的例子。另一個泛型類UsesExample使用它作爲約束,並使用new()約束。後來,我創建了一個子類Example Example,並將其用於泛型類。但是,不管怎樣,當泛型類中的代碼嘗試創建新副本時,它不會調用子類中的構造函數,而是調用父類中的構造函數。爲什麼會發生? 下面的代碼:爲什麼父母的構造函數被調用?

abstract class Example { 

    public Example() { 
     throw new NotImplementedException ("You must implement it in the subclass!"); 
    } 

} 

class ExampleChild : Example { 

    public ExampleChild() { 
     // here's the code that I want to be invoken 
    } 

} 

class UsesExample<T> where T : Example, new() { 

    public doStuff() { 
     new T(); 
    } 

} 

class MainClass { 

    public static void Main(string[] args) { 

     UsesExample<ExampleChild> worker = new UsesExample<ExampleChild>(); 
     worker.doStuff(); 

    } 

} 

回答

8

當你箱對象,所有構造函數的調用。首先,基類構造函數構造對象,以便初始化基類成員。之後調用層次結構中的其他構造函數。

此初始化可能調用靜態函數,因此如果它沒有數據成員,則調用抽象基類事件的構造函數是有意義的。

+0

你能肯定嗎?我不是100%關於C#,但通常調用父的構造函數需要顯式調用super()(以Java的方式) –

+0

他是正確的,你可以看我在我的答案中提供的鏈接(其中之一是msdn) – YavgenyP

+0

@MK:這是正確的。在C#中,總是調用父構造函數。如果你不指定':this()'或':base()'調用,它將自動調用無參數的構造函數。 – Guffa

8

每當您創建派生類的新實例時,都會隱式調用基類的構造函數。由編譯器

public ExampleChild() : base() { 
    // here's the code that I want to be invoked 
} 

:在你的代碼,

public ExampleChild() { 
    // here's the code that I want to be invoked 
} 

真的變成。

您可以閱讀關於Jon Skeet關於C#構造函數詳細的blog的文章。

2

在派生類中,如果沒有使用base關鍵字明確調用基類構造函數,那麼隱式地調用默認構造函數(如果有)。

msdn 也可以讀取here

+1

爲了澄清,如果沒有對基類的顯式調用,並且它沒有可訪問的默認構造函數,那麼代碼將不會編譯。 – Guffa

相關問題