转换函数<对象,任务>to Func在运行时
本文关键字:Task 运行时 Func to 函数 任务 转换 对象 | 更新日期: 2023-09-27 18:07:51
我有一个Func<object, Task>
。我试图把它作为一个参数传递给一个函数,它接受Func<T, Task>
。我使用反射为该函数创建MethodInfo
,并且填充的T
直到运行时才知道。
如何使用反射来实现这一点?
你不需要做任何特别的事情
Func<in T, out TResult>
是T
的逆变 -它的输入参数,并且每个类型都继承自object
,这意味着您可以将任何引用类型 T
的强制转换 Func<object, Task>
到Func<T, Task>
-按原样传递它,它将正常工作。
现在,这对值类型不起作用,因为这些值类型需要事先将拆箱。
所以,如果你的T
是一个值类型,你必须包装它在另一个委托将执行强制类型转换。
private static Func<T, TResult> CastFunc<T, TResult>(Func<object, TResult> fn)
=> param => fn(param);
然后通过反射创建一个委托:
var result = (Func<int, Task>)typeof(WrapperClass)
.GetMethod(nameof(CastFunc), BindingFlags.NonPublic | BindingFlags.Static)
.MakeGenericMethod(typeof(int), typeof(Task)).Invoke(null, new object[] { fn });
我会选择使用MakeGenericMethod
下面是一个简单的例子:
public class Example
{
public void Start()
{
Func<object, Task> func = o => null;
object objFunc = func; // got it from a generic place as an object or something
Type type = objFunc.GetType().GetGenericArguments()[0]; // get T in runtime
var method = typeof(Example).GetMethod("DoSomething", BindingFlags.Public | BindingFlags.Instance).MakeGenericMethod(type);
var result = method.Invoke(this, new object[1] { func });
}
public int DoSomething<T>(Func<T, Task> input)
{
return 1;
}
}