2011-02-03 101 views
1

我正要通過對反射和泛型的一些文章,我碰到下面的代碼來:優勢Activator.CreateInstance的

public static T CreateControlInstance<T>(FormControl parent) 
    where T : FormControl 
{    
    T control = GetControlInstance<T>(parent); 
    //do something with control 
} 

public static T GetControlInstance<T>(FormControl parent) 
{ 
     return (T)Activator.CreateInstance(typeof(T), new object[] { parent }); 
} 

這些方法中使用這樣的:

MyButton b = CreateControlInstance<MyButton>(SomeformInstance); 

許多控件是以這種方式創建的。我只想知道:

Q1。這種方法的優點是什麼?

Q2。考慮到對象實例類型在編譯時已知,這種方法的優點是什麼? (我假設的按鈕和FormControl以某種方式與System.Windows.Forms.Control

編輯:
我發現這裏類似的事情正在做 Create instance of generic type?

基本上我想創建(已知類型的)類型從運行時讀取的字符串?
我想避免if-then-else根據字符串創建具體類型的對象的長列表..但沒有線索。
任何人都有更好的解決方案,以避免反射以創建已知類型的元素。
末編輯

+0

您可以添加對文章的引用嗎? – 2011-02-03 11:47:12

+0

這是一個人爲的例子。也不是很好的一個,命名的選擇是一個可怕的。 GetFooInstance不*建議創建* new * Foo。 – 2011-02-03 12:30:13

回答

3

與仿製藥的問題是,你不能在複雜的構造函數定義約束。唯一的約束是空構造函數的可用性。

public static T CreateInstance<T>() where T : new() 
{ 
    return new T(); 
} 

但是,如果你想傳遞參數,你必須用其他的方法,如Activator.CreateInstance。你也可以使用lambda。

public static T CreateInstance<T>(Func<FormControl, T> builder, FormControl parent) 
{ 
    return builder(parent); 
} 

但是你必須提供一個特定的lambda來構造你的對象,爲每個不同的對象。

MyButton b = CreateInstance<MyButton>(parent => new MyButton(parent), SomeformInstance); 

通過使用反射,可以使代碼更簡單,並自動使用預先定義的構造函數。但通過使用lambda,可以使用不符合給定約定的類,並使用自己的數據填充其他構造函數參數。

var b2 = CreateInstance<MyOtherButton>(
    parent => new MyOtherButton("name", 42, parent), SomeformInstance 
); 
0

唯一的優點是您可以執行額外的處理。

你可以例如用一些額外的處理來擴展CreateControlInstance<T>方法,這需要執行以前的控制。

然而,當選擇的是有絕對

之間
MyButton b = CreateControlInstance<MyButton>(SomeformInstance); 

MyButton b = new MyButton(SomeformInstance); 

沒有理由不選擇後者。前者會表現得更差,會不必要地混淆你的代碼。

2

如果你打算用這種方式創建很多控件,你會注意到你的應用程序運行緩慢。這是因爲Activator.CreateInstance比簡單的new()慢10000倍。請牢記這一點。