具有运行时已知类型的表达式 Lambda
本文关键字:表达式 Lambda 类型 运行时 | 更新日期: 2023-09-27 17:56:23
我正在尝试制作一些表达式,我将在其中使用 lambda 创建两个方法:选择器和条件。简化用法condition(selector(data))
,但中间类型仅在运行时已知。我有以下代码,只要中间类型是对象,它就可以工作,但在运行时我知道真正的类型并想使用它。
public static ICondition<TData> GetRelayConditionByReflection(string name, string message, string assemblyName,
string fullyQualifiedName, string conditionMethodName, string selectorMethodName) {
var asm = Assembly.LoadFrom(assemblyName);
var type = asm.GetType(fullyQualifiedName);
var selectorMi = type.GetMethod(selectorMethodName, BindingFlags.Static | BindingFlags.Public);
var conditionMi = type.GetMethod(conditionMethodName, BindingFlags.Static | BindingFlags.Public);
var tCondType = selectorMi.ReturnType;
var returnType = typeof(RelayCondition<,>);
var typeArgs = new[] { typeof(TData), tCondType };
var paramTData = Expression.Parameter(typeof(TData), "data");
var selector = Expression.Lambda<Func<TData, object>>(
Expression.Call(selectorMi, paramTData), paramTData).Compile();
var paramTCondition = Expression.Parameter(tCondType, "condition");
var condition = Expression.Lambda<Func<object, bool>>(
Expression.Call(conditionMi, paramTCondition), paramTCondition).Compile();
return (ICondition<TData>)Activator.CreateInstance(returnType.MakeGenericType(typeArgs), name, condition, message, selector);
}
具体来说,存在Expression.Lambda<Func<TData, object>>
和Expression.Lambda<Func<object, bool>>
,其中object
当前仅允许中间类型为对象。
是否可以使用仅在运行时知道的类型创建此类型?对于整个问题,我愿意采用其他方法,只要性能不受影响。
如果你不需要隐式下灌(例如,当你的方法返回一个Func<Foo>
时声明一个Func<object>
),你可以使用非泛型Expression.Lambda()
方法。它返回一个LambdaExpression
,但实际上它返回一个Func<>
或Action
向下转换为LambdaExpression
的Expression<>
(Expression<>
是LambdaExpression
的子类),因此:
var condition = Expression.Lambda(
Expression.Call(conditionMi, paramTCondition), paramTCondition).Compile();
现在condition
是一个Delegate
,但实际上它是一个Func<>
(如果它有一个返回类型void
,则是一个Action
)。