我需要用Action<T>
构建一个表达式树(如果我可以这样表述的话),但问题是类型T
是在运行时通过反射确定的。
我需要将此表达式作为参数传递给使用MethodInfo.Invoke
API 调用的泛型方法。此方法的类型参数和上面提到的 lambda 应该匹配。
这是可以实现的吗?或者也许有一些更好/更简单的方法可以做到这一点?
该方法如下所示:
static GenericMethod<T>(Expression<Action<T>> doSomething) { }
我所需要的只是打电话,例如
Class.GenericMethod<string>(s => { Console.Write(s.GetType()); }
但我需要在运行时动态执行此操作。
似乎您已经知道如何获取和调用泛型方法GenericMethod
:
var genericMethod = someType.GetMethod(nameof(GenericMethod), BindingFlags.NonPublic | BindingFlags.Static);
genericMethod.MakeGenericMethod(type).Invoke(null, …);
您可能还知道如何创建一个基于编译时T
创建所需表达式的方法:
static Expression<Action<T>> CreateWriteTypeExpression<T>() =>
s => Console.Write(s.GetType());
那么,如何根据运行时Type
调用此CreateWriteTypeExpression
呢?与上述相同,用于GenericMethod
,使用反射。
放在一起将是:
static Expression<Action<T>> CreateWriteTypeExpression<T>() =>
s => Console.Write(s.GetType());
void CallGenericMethod(MethodInfo genericMethod, Type type)
{
var writeTypeExpressionMethod = this.GetType()
.GetMethod(nameof(CreateWriteTypeExpression), BindingFlags.NonPublic | BindingFlags.Static)
.MakeGenericMethod(type);
var writeTypeExpression = writeTypeExpressionMethod.Invoke(null, null);
genericMethod.MakeGenericMethod(type).Invoke(null, new[] { writeTypeExpression });
}