【发布时间】:2021-03-11 00:37:01
【问题描述】:
我正在尝试获取 MethodInfo 并将其转换为可调用的 Func。我已经使用方法签名的同步函数成功地做到了这一点:
public AnyObject MyFuncName(AnotherObject message, IMessage messageMetadata)
AnyObject 和 AnotherObject 是任何类。在使用反射提取 MethodInfo 之后,我使用以下代码完成了此操作:
public static Func<Handler, object, IMessage, object> CompileHandler(Type handler, MethodInfo method, Type argumentType)
{
var instance = Expression.Parameter(typeof(Handler), "instance");
var messageParam = Expression.Parameter(typeof(object), "message");
var messageMetaParam = Expression.Parameter(typeof(IMessage), "messageMetadata");
var methodCall = Expression.Call(
Expression.Convert(instance, handler),
method,
Expression.Convert(messageParam, argumentType),
Expression.Convert(messageMetaParam, typeof(IMessage)));
return Expression.Lambda<Func<Handler, object, IMessage, object>>(
methodCall,
instance,
messageParam,
messageMetaParam).Compile();
}
以上工作。它将创建Func,我可以调用该函数。我现在正在尝试使我正在反映的函数异步,并且将具有确切的签名,除非它的返回类型为Task<AnyObject>,它被转换为Func<Handler, object, IMessage, Task<object>>
但是,当我将上面的所有引用 Func<Handler, object, IMessage, object> 更改为 Func<Handler, object, IMessage, Task<object>>
当我这样做时,Expression.Lambda 会抛出这个异常:
Initialization method HandlerUnitTests.TestInitialize
threw exception. System.ArgumentException: System.ArgumentException: Expression of type
'System.Threading.Tasks.Task`1[Handler.AnyObject]' cannot be used for return type
'System.Threading.Tasks.Task`1[System.Object]'
但是,当 Func 签名为Func<Handler, object, IMessage, object> 时,将返回类型转换为对象时,它没有这样的反对意见
编辑:这里的问题是我如何实现上述目标?
【问题讨论】:
-
您可以编辑您的问题标题并总结您要在此处解决的问题吗?请参阅How to Ask 了解更多信息。
-
您不能将
Task<T>转换为Task<object>,但您可以编写一个辅助异步方法,该方法接受Task<T>并返回Task<object>并在您的表达式中调用它。跨度> -
@JeremyLakeman 你有任何示例代码可以帮助我更好地理解这一点吗?感谢您的回复!
标签: c# reflection