2009-09-16 200 views
7

我試圖構建一個使用的C#泛型功能的工廠方法。C#泛型 - 約束的類型參數

在此工廠方法我想將其約束到一些特定的類,所有這些沒有一個默認的構造函數。

這裏是我的榜樣。有人能告訴我是否可以運行它嗎?

public class AbstractClass { 
    //this abstract class does not have a default constructor, nor its subclasses 
    public AbstractClass(SomeClassName obj) { 
     //use obj for initialization 
    } 
} 

//this factory class should create objects of type T that inherit 
//from AbstractClass and invoke the non-default constructor 
public class FactoryClass { 
    public static T BuildObject<T> (SomeClassName obj) where T: AbstractClass { 
     return new T(obj); //does not work?!?!?! 
    } 
} 


//Edit: ANSWER!!! 
public static T BuildObject<T>(SomeClassUsedForTheConstructor item) where T : SomeAbstractClass { 
return (T) Activator.CreateInstance(typeof (T), item); 
} 

回答

4

看那Type類和GetConstructor。獲得ConstructorInfo對象後,使用Invoke方法。

var x = typeof(T); 
var t = x.GetConstructor(new[] {obj.GetType()}); 
object u = t.Invoke(<inputs>); 
+0

這是我以前使用的,但現在我使用Brian提到的Activator.CreateInstance。 – 2009-09-16 18:59:53

3

不,您正在嘗試使用的內置通用約束條件是不可能的。 新的關鍵字僅允許您將泛型類型約束爲具有默認構造函數。

+0

並且只有在T:new()被定義的情況下。 – 2009-09-16 18:44:29

4

我不認爲你可以實例化泛型類型,而a default constructor的約束類型。

請考慮,而不是指定的接口IAbstractClass,這樣,你的工廠類可以設置SomeClassName參數作爲IAbstractClass的屬性。

此外,如果需要初始化一個抽象類的實例SomeClassName,想想也有一個空的默認構造函數,但在IAbstractClass定義豐富的初始化方法。例如:

public interface IAbstractClass { void Initialize(SomeClassName obj); } 

這樣一來,你的靜態BuildObject方法,而不是做:

public static T BuildObject<T>(SomeClassName obj) where T: AbstractClass 
{ 
    T newObject = new T(); 
    IAbstractClass ac = newObject as IAbstractClass; 
    ac.Initialize(obj); 
} 
5

我喜歡在仿製藥需要創建類型T的新對象它的作品真的很好用Activator.CreateInstance(typeof(T))

+0

這應該進入.net岩石播客!感謝你的回答。 – Pablo 2009-09-16 19:23:34

+0

//最終代碼 public static T BuildObject (SomeClassUsedForTheConstructor item)其中T:SomeAbstractClass { return(T)Activator.CreateInstance(typeof(T),item); } – Pablo 2009-09-16 19:25:05

+2

這很慢,沒有編譯時檢查... – 2009-09-16 19:39:47