通过具有委托参数的反射调用泛型方法时出现问题

本文关键字:泛型方法 调用 问题 反射 参数 | 更新日期: 2023-09-27 18:19:59

我已经折腾了一个多小时了,似乎就是做不好。以下是我遇到的一个例外:

错误:System.Func1[System.Object]类型的对象不能是转换为类型CCD_ 2。

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

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参数?

通过具有委托参数的反射调用泛型方法时出现问题

问题是您没有正确指定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。但是,为调用构造的泛型方法callback而传递的Func参数是这样定义的:

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));
} 

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

我设法通过将KeyValuePair的返回更改为:来对其进行排序

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));
} 

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