在没有新约束的情况下创建T的新实例

Dav*_*New 12 .net c# generics reflection instantiation

如果想要创建泛型的新实例,则需要定义新约束,如下所示:

public T SomeMethod<T>() where T : new()
{
    return new T();
}
Run Code Online (Sandbox Code Playgroud)

是否可以使用反射在没有新约束的情况下创建T的实例,如此(包含伪代码):

public T SomeMethod<T>()
{
    if (T has a default constructor)
    {
        return a new instance of T;
    }
    else
    {
        return Factory<T>.CreateNew();
    }
}
Run Code Online (Sandbox Code Playgroud)

Pie*_*kel 16

使用Activator.CreateInstance()此.有关如何使用此方法的详细信息,请参阅http://msdn.microsoft.com/en-us/library/system.activator.createinstance.aspx.基本上,你做的是:

var obj = (T)Activator.CreateInstance(typeof(T));
Run Code Online (Sandbox Code Playgroud)

您可以使用以下GetConstructors()方法验证它是否具有默认构造函数:

var constructors = typeof(T).GetConstructors();
Run Code Online (Sandbox Code Playgroud)

如果找到参数为零的构造函数,则可以使用该Activator.CreateInstance方法.否则,您使用该Factory<T>.CreateNew()方法.

编辑:

要直接找出没有任何参数的构造函数,可以使用以下检查:

if (typeof(T).GetConstructor(Type.EmptyTypes) != null)
{
    // ...
Run Code Online (Sandbox Code Playgroud)

  • 只是在`GetConstructors()`的东西 - `typeof(T).GetConstructor(Type.EmptyTypes)`可能更具体 - 返回`null`或non-`null`. (3认同)

Mar*_*ell 10

具有where T : new()约束的通用方法new T()通过调用实现调用Activator.CreateInstance<T>().关于这个方法的一个有趣的事情是它不包含约束,所以如果你很乐意将检查推迟到运行时,只需使用:

public T SomeMethod<T>() {
    return Activator.CreateInstance<T>();
}
Run Code Online (Sandbox Code Playgroud)

这将要么究竟做什么return new T() 都做了,或将引发一个有意义的异常.因为它处理成功和失败的情况,所以进行任何额外的检查没有任何实际好处,除非你想做一些模糊的事情,比如根本不使用构造函数(可以这样做).