2009-08-17 123 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?

相关问题