2009-08-17 121 views
25

我已經在線閱讀了一些關於此主題的小技巧,但發現沒有一項適用於我。 我想要做的是創建一個運行時類型的類。Activator.CreateInstance - 如何創建具有參數化構造函數的類的實例

我使用Activator.CreateInstance它適用於具有不包含參數的構造函數的類。對於那些有參數的人來說,它會拋出一個異常,有沒有辦法解決這個問題呢?

我非常樂意將空值或空值傳遞給ctor,只要我可以創建類本身。

+0

(回覆評論) – 2009-08-17 17:43:46

+0

問題不重複,但答案是:http://stackoverflow.com/questions/731452/create-instance-of-generic-type的 – nawfal 2013-04-23 07:53:54

+0

可能重複[如何將參數傳遞給Activator.CreateInstance ()](http://stackoverflow.com/questions/2451336/how-to-pass-parameters-to-activator-createinstancet) – 2013-04-26 16:43:48

回答

7

我終於結束了做這樣的事情 - 一些無論如何,評論者都暗示這個解決方案。

我基本上遍歷所有可用的構造函數,並選擇最簡單的。然後,我創建空數據傳遞到構造函數(什麼即時通訊使用它的這種做法是罰款)

代碼

部分看起來有點像這樣

// If we have a ctor that requires parameters then pass null values 
if (requiresParameters) 
{ 
    List<object> parameters = new List<object>(); 
    ParameterInfo[] pInfos = constructorInfos[0].GetParameters(); 

    foreach (ParameterInfo pi in pInfos) 
    { 
     parameters.Add(createType(pi.ParameterType)); 
    } 

    return constructorInfos[0].Invoke(parameters.ToArray()); 
} 
+0

'constructorInfos [0] .GetParameters()。Select(pi => createType(pi.ParameterType))。ToArray()' – ErikE 2015-09-10 22:27:12

46

有一個允許的參數作爲params object[]過載:

object obj = Activator.CreateInstance(typeof(StringBuilder), "abc"); 

請問這怎麼辦?此外,也可以使用反射來找到正確的構造函數:

Type[] argTypes = new Type[] {typeof(string)}; 
object[] argValues = new object[] {"abc"}; 
ConstructorInfo ctor = typeof(StringBuilder).GetConstructor(argTypes); 
object obj = ctor.Invoke(argValues); 
+0

只是出於好奇,從性能的角度來看會更好:通過反射獲取構造函數列表並調用特定的構造函數,或直接使用object []調用Activator.CreateInstance? – 2009-08-17 14:44:51

+1

我期待ConstructorInfo方法。否則,它必須考慮哪些值與哪些構造函數兼容 - 特別是如果您傳遞了「null」等(可能與多個構造函數匹配)。 – 2009-08-17 17:39:56

+1

但是你可以這麼做;事實上,如果性能是一個重要的考慮因素,你可能會遇到預編譯的表示構造函數的LINQ表達式(因爲這是.NET 3.5)。讓我知道你是否想要一個這樣的例子。 – 2009-08-17 17:41:02

0

Activator.CreateInstance也有一大堆重載,一個你可能想看看是(類型類型,params對象[]參數)。只需將所需的構造函數參數提供給此調用的第二個參數即可。

確保您處理異常這裏雖然,因爲它很容易通過或東西在類型的構造函數以後,打破它改變不正確的參數..

1

我用這個方法來獲得大約在an issue I ran into,它似乎正如我所希望的那樣工作。 :)

object instance = Activator.CreateInstance(
    typeof(OpCode), 
    BindingFlags.NonPublic | BindingFlags.Instance, 
    default(Binder), 
    new object[] { stringname, pop, push, operand, type, size, s1, s2, ctrl, endsjmpblk, stack }, 
    default(CultureInfo)); 
+0

是否可以用於任何類型...? – Chris 2009-08-20 10:44:25

0

正如所鏈接的URL瓶坯比活化劑更好的替代方法Activator.CreateInstance,FastObjectFactory(作爲.NET 4.0和顯著優於.NET 3.5。沒有測試/統計與.NET 4.5完成) 。請參閱StackOverflow發佈統計信息和代碼。請注意,可能需要根據ctor參數的數量進行一些修改。所提供的代碼只允許1個ctor參數,但可以修改爲具有多個參數。請參閱代碼中的註釋。

How to pass ctor args in Activator.CreateInstance or use IL?

相關問題