如何向 Activator.CreateInstance<T>() 传递参数

296

我想在一个泛型方法中创建一个指定类型的实例。该类型有多个重载构造函数。我想能够向构造函数传递参数,但是

Activator.CreateInstance<T>()

似乎没有这个选项。

还有其他方法可以做到吗?


5个回答

565

Yes.

(T)Activator.CreateInstance(typeof(T), param1, param2);

1
这是不正确的,如果你的 param1 是一个布尔值,这将会失败,因为 https://learn.microsoft.com/en-us/dotnet/api/system.activator.createinstance?view=net-7.0#system-activator-createinstance(system-type-system-boolean) 中有相关说明。 - undefined
这是不正确的,如果你的 param1 是一个布尔值,这将会失败,因为 https://learn.microsoft.com/en-us/dotnet/api/system.activator.createinstance?view=net-7.0#system-activator-createinstance(system-type-system-boolean) 中有说明。 - gangfish

35
通过命名参数,还有另一种方法来传递参数给CreateInstance。
基于此,您可以将一个数组传递给CreateInstance。这将允许您拥有0个或多个参数。
public T CreateInstance<T>(params object[] paramArray)
{
  return (T)Activator.CreateInstance(typeof(T), args:paramArray);
}

21
编辑: 自从这个答案发布以来,.NET 7中的情况发生了变化。请参阅本文了解性能改进。

https://devblogs.microsoft.com/dotnet/performance_improvements_in_net_7/

感谢@balrob在评论中的提醒。
请记住,在Activator.CreateInstance中传递参数与无参创建相比,性能差异显著。
使用预编译的lambda表达式动态创建对象有更好的替代方案。当然,性能因情况而异,是否值得取决于每个具体情况。 有关此问题的详细信息,请参阅本文。 图表取自该文章,并表示每1000次调用所花费的时间(以毫秒为单位)。

Performance comparison


11
这张图表意味着(在相同的硬件上平均而言),每次使用Activator.CreateInstance调用参数化构造函数所需的时间为0.0035毫秒(或3.5微秒)- 根据你的应用程序,这甚至可能不会在性能测试中产生明显影响。 - Dai
哎呀!有时候老方法确实更好。肯定不会使用Activators。那性能太差了! - MC9000
1
引用的文章来自2010年,很可能已经不适用了。在.NET 7的性能注释中,CreateInstance()被指出具有显着更快的速度。 - balrob
虽然它更快了,但对于它的性能来说,仍然显得不合理地慢...我刚刚用.NET 7和8进行了基准测试。 - undefined

6

你的意思是说,当你传递参数时,有一个替代方案(链接)可能比Activator.CreateInstance表现更好?还是在所有情况下都可能表现更好? - El Zorko
1
我已经有一段时间没有进行性能测试了,看起来有人发布了.NET 4.0的统计数据,但是确实使用.NET 4.0时,FastObjectFactory的性能更好。在.NET 3.5中,Activator.CreateInstance表现很差,在.NET 4.0中明显快了很多,但仍然比链接中的FastObjectFactory慢。 - thames

-3
public class AssemblyLoader<T>  where T:class
{
    public void(){
        var res = Load(@"C:\test\paquete.uno.dos.test.dll", "paquete.uno.dos.clasetest.dll") 
    }

    public T Load(string assemblyFile, string objectToInstantiate) 
    {
        var loaded = Activator.CreateInstanceFrom(assemblyFile, objectToInstantiate).Unwrap();

        return loaded as T;
    }
}

3
这是一段纯代码,没有解释。我怀疑它是否有用,甚至能否正常运行。如果想要让我改变看法,请说明其工作原理以及为什么它可以解决问题。 - Yunnosch

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接