C# 如何使用类型为“Type”的对象初始化泛型类

本文关键字:对象 初始化 泛型类 Type 何使用 类型 | 更新日期: 2023-09-27 18:33:16

我最近遇到了这个问题。

doSomething(typeof(int));
doSomething(typeof(MyClassA));
doSomething(typeof(MyClassB));
public void doSomething(Type _type)
{
    var myGenObj = new MyGenericClass<_type>();  // Error.  Really I'd want MyGenericClass<int>, MyGenericClass<MyClassA>, etc depending on what's passed in.
    myGenObj.doSomeGenStuff();
    // more stuff...
}

我认为这可以通过反思以某种方式完成。可能有一种更简单的方法。我一直对类型与幕后的类如何工作感到有些困惑。无论如何,感谢您的任何帮助。

谢谢。

C# 如何使用类型为“Type”的对象初始化泛型类

你想要Type.MakeGenericType然后Activator.CreateInstance...但是,在新创建的对象上调用方法将很棘手。理想情况下,您可以有一个包含这些成员的非泛型基类或接口:

public interface IFoo
{
    void CallSomeMethod();
}
public class MyGenericClass<T> : IFoo
{
    ...
}
// Names changed to be more conventional
public void DoSomething(Type type)
{
    var genericType = typeof(MyGenericClass<>).MakeGenericType(type);
    var instance = (IFoo) Activator.CreateInstance(genericType);
    instance.CallSomeMethod();
}

如果确实需要调用依赖于类型参数的方法,则需要使用反射可以简化基于反射的代码dynamic来执行此操作。

编辑:正如cdhowie所说,如果你总是在编译时真正知道类型,你可以使用一个通用方法,这将使事情变得更加简单。然后,您可以像这样调用该方法:

DoSomething<int>();
DoSomething<MyClassA>();
DoSomething<MyClassB>();

像这样:

object myGenObj = Activator.CreateInstance(typeof(MyGenericClass<>).MakeGenericType(_type));

但是,由于生成的对象属于您在编译时不知道的类型,因此您无法通过泛型类型(除非通过反射)真正调用对象的成员。 如果在编译时知道某个祖先类型或实现的接口,则可以强制转换为该类型或实现的接口,然后调用该成员。

您还可以考虑将此功能包装在泛型方法中,这使得整个事情更容易处理:

public void doSomething<T>()
{
    var myGenObj = new MyGenericClass<T>();
    myGenObj.doSomeGenStuff();
}

如果必须支持Type对象,则可以使用使用反射作弊的重载:

public void doSomething(Type _type)
{
    this.GetType().GetMethod("doSomething", Type.EmptyTypes)
        .MakeGenericMethod(_type)
        .Invoke(this, null);
}