使用委托参数通过反射调用泛型方法的问题

Issues in calling generic method through reflection with a delegate parameter

我已经弄乱了一个多小时,但似乎无法正确处理。这是我遇到的例外情况之一:

Error: Object of type System.Func1[System.Object] cannot be converted to type System.Func1[System.Collections.Generic.IEnumerable1[System.Collections.Generic.IEnumerable1[System.Object]]].

基本上我有一个看起来像这样的通用工厂方法

ReturnItem<TResult> CreateOutput<T, TResult>(Func<IEnumerable<T>> postBack,
    Processor manager) where TResult : class;

我正在尝试反映,但 Func<IEnumerable<T>> 给我带来了问题。这是我尝试调用它的代码:

var infer = Factory.CreateReturnInference(); //Keypair value (type, type) is NOT an NormalOutputFactory in this instance
Func<object> callBack = () => subTypes;

var toRun = Factory.GetType()
            .GetMethod("CreateOutput", BindingFlags.Public | BindingFlags.Instance)
            .MakeGenericMethod(infer.Key, infer.Value)
            .Invoke(Factory,
                new object[] {callBack, Manager}) as
            ReturnItem<object>;

Factory.CreateReturnInference 返回的密钥对值用于指定通用参数,只是为了提供其实现的清晰度(警告非常丑陋的代码,违反了打开关闭数量其他东西:)):

public KeyValuePair<Type, Type> CreateReturnInference()
    {
        return this is NormalOutputFactory
            ? new KeyValuePair<Type, Type>(typeof (object), typeof (Log))
            : new KeyValuePair<Type, Type>(typeof (IEnumerable<object>), typeof (Enum));
    } 

一般问题是:通过反射调用泛型方法时,如何指定 Func 参数?

我设法通过将 KeyValuePair 的 return 更改为这个来解决这个问题:

public KeyValuePair<Type, Type> CreateReturnInference()
{
    return this is NormalOutputFactory
        ? new KeyValuePair<Type, Type>(typeof (object), typeof (object))
        : new KeyValuePair<Type, Type>(typeof (IEnumerable<object>), typeof (object));
} 

仍然不太高兴这样做,但解决了问题

问题是您没有正确指定 Func<T> 参数。换句话说,您传递给 CreateOutput 方法的类型不正确。当你这样做时:

MakeGenericMethod(infer.Key, infer.Value)

方法的类型参数

ReturnItem<TResult> CreateOutput<T, TResult>(Func<IEnumerable<T>> postBack, ...)

您超过的是 typeof(IEnumerable<object>)typeof(Enum)。因为你

return new newKeyValuePair<Type, Type>(typeof(IEnumerable<object>), typeof(Enum));

因此,您尝试创建的 CreateOutput 方法具有如下签名:

ReturnItem<Enum> CreateOutput(Func<IEnumerable<IEnumerable<object>>> postBack, ...)

也就是说,T变成了IEnumerable<object>TResult变成了Enum。但是您传递给调用构造的泛型方法 callbackFunc 参数定义如下:

Func<object> callBack = () => subTypes;

您的解决方案是:

1) 像这样更改 callback 的签名:

Func<IEnumerable<IEnumerable<object>>> callBack = () => subTypes;

2) 或者通过调整键值对函数来更改泛型方法的参数类型。

Func<IEnumerable<object>> callBack = () => subTypes;

public KeyValuePair<Type, Type> CreateReturnInference()
{
    return ... new KeyValuePair<Type, Type>(typeof(object), typeof(Enum));
} 

我想第二个是你想要的,但我不能确定。