在运行时使用反射构造泛型的具体类型的实例

本文关键字:类型 实例 泛型 运行时 反射 | 更新日期: 2023-09-27 18:11:39

考虑以下类:

public class GenericClass<T>
{
   public T Argument;                
}

第二个类引用并使用GenericClass:

public class ClientClass
{
    GenericClass<T> genclass = new GenericClass<T>();
}

我的问题是我在编译时不知道T的类型。我在运行时使用反射来获取t的类型。是否有可能在实例化GenericClass时以某种方式使用参数化表达式?

在运行时使用反射构造泛型的具体类型的实例

可以,但是您必须使用反射来构建您正在寻找的实际类型。

首先需要通过使用typeof操作符获得开放泛型:

var openType = typeof(GenericClass<>);

接下来,需要构建所需的特定泛型。假设您想要的类型T存储在变量type中:

var closedType = openType.MakeGenericType(type);

最后,使用反射创建该类型的实例。

object instance = Activator.CreateInstance(closedType);
但是,正如xanatos在评论中指出的那样,您应该意识到这会导致object类型的成员。为了能够在没有反射的情况下操作对象,您有两种选择。
  1. 您可以创建父类GenericClass, GenericClass<T>从它派生,并在它上面包含所有通用的方法。(即GenericClass包含不需要使用T的成员。
  2. 正如Ingenu在问题的评论中提到的,你可以创建一个接口IInterface,然后在T, where T : IInterface上添加一个限制。然后,您可以将instance转换为GenericClass<IInterface>并以这种方式操作它。显然,在这种情况下type必须实现IInterface

当然,您也可以只保留object引用并仅使用反射来操作它,或者使用dynamic来后期绑定任何方法调用——然而,这在底层使用了反射。