调用具有泛型参数类型的子类型的泛型方法

本文关键字:类型 泛型方法 参数 泛型 调用 | 更新日期: 2023-09-27 18:09:52

我试图通过使用泛型参数类型的子类型的反射调用泛型方法。情况如下:

public abstract class MyClass<T> where T : class
{
}
public static class Caller
{
    public static void Do<T>(MyClass<T> param1, string param2 = null) where T : class
    {
    }
}
public class ConcreteClass : MyClass<string>
{
}

但是当我尝试做:

ConcreteClass instance = Activator.CreateInstance(typeof(ConcreteClass));
MethodInfo methodInfo = typeof(Caller).GetMethod("Do");
methodInfo = methodInfo.MakeGenericMethod(typeof(ConcreteClass));
methodInfo.Invoke(null, new object[] { instance, Type.Missing });

我得到一个异常,本质上说:

无法将类型'ConcreteClass'转换为类型'MyClass ' [ConcreteClass]'

异常消息非常清楚,但我似乎找不到我如何才能实现我所追求的。

编辑:

我想要达到的编译时间等效是:

Caller.Do(new ConcreteClass());

调用具有泛型参数类型的子类型的泛型方法

ConcreteClass扩展MyClass<string>,因此您需要将typeof(string)提供给MakeGenericMethod:

ConcreteClass instance = (ConcreteClass)Activator.CreateInstance(typeof(ConcreteClass));
MethodInfo methodInfo = typeof(Caller).GetMethod("Do");
methodInfo = methodInfo.MakeGenericMethod(typeof(string));
methodInfo.Invoke(null, new object[] { instance, Type.Missing });

您的基于反射的代码正在尝试运行时相当于Caller.Do<ConcreteClass>(instance, Type.Missing)

无效。方法Do<>需要匹配类型——对于Do<ConcreteClass>,您需要一个实例是或是MyClass<ConcreteClass>的子类。

ConcreteClassMyClass<string>的子类。为此,您需要调用Do<string>(instance),或者总体上调用Caller.Do<string>(instance, Type.Missing)