2015-04-28 165 views
0

我有一個抽象基類和幾個派生自它的類。基地級別對所有的約定都有一些我喜歡使用的構造函數。 我正在寫一個擴展方法,它採用泛型類型參數。這種類型的返回類型:使用泛型類型的參數化構造函數基類

public static T Create<T>(string key) where T : Baseclass { } 

現在,我想訪問基類的構造函數,例如:

var item = new T(key); 

當基類定義了相應的構造函數。

我知道,它可能是一個非常糟糕的設計,並且有使用反射(天真的方式)或委託函數或將構造函數調用放在Create()之外的解決方法。

我只是好奇,爲什麼C#-Compiler不允許訪問構造函數的抽象基類中定義的泛型類型,泛型類型必須從泛型類型約束派生出來。

有幾個問題,幾乎相似,但他們都關心約束泛型類型的構造函數,在我的情況下約束是類繼承。

回答

0

嗯,首先你缺少的new()約束,它允許一個泛型類型,即

public static T Create<T>(string key) where T : Baseclass, new() 
{ 
    ... 
} 

不過的建設,給你需要的參數傳遞給構造函數,只有結果更換一個錯誤another 。解決此問題的辦法是避免構造器注入(如果可能),去參數注入,而不是

var item = new T(); 
item.Key = key; 

如果是構造器注入,那麼如你所說,你幾乎僅限於使用反射。

+0

這就是我一直以來的觀點。我知道編譯器不考慮基類中的構造函數,當然還有其他方法和屬性。實際上,我已經使用了一種不同的方法(我在'Create'之外調用構造函數,傳遞實例而不是密鑰,並在不需要的情況下進行處理)。有趣的問題是:爲什麼C#有這樣的限制?實際問題還是真正的概念問題? –

+0

@PatrikEckebrecht實際上它不能看到* base *類的構造函數,它更多的是因爲編譯器不支持調用泛型,參數化構造函數。至於*爲什麼*,請參閱Eric Lipperts [answer](http://stackoverflow.com/questions/9741211/restricting-a-generic-type-parameters-to-have-a-specific-constructor/9741812#9741812)關於這個話題。 – James

+0

Eric Lippert在那裏指出,在泛型類型參數約束中支持任何方法簽名的東西是一個壞主意。這不是我要求的:我不想在約束中定義構造函數,而是在基類中定義構造函數。正如他所說的,構造函數是一種方法,爲什麼編譯器在使用泛型類型時允許訪問所有方法,而不是構造函數。根據他的回答,實際上應該可以按照我的建議調用構造函數。 –