我正在尝试在运行时动态选择Expression
中的方法。例如,我想要实现与以下尝试类似的功能:
ConstantExpression one = Expression.Constant(1);
ConstantExpression two = Expression.Constant(2);
// Here the 'GreaterThan' is the method name received at runtime:
var method = typeof(Expression).GetMethods().Single(mi => mi.Name == "GreaterThan" && mi.GetParameters().Length == 2);
var expr = Expression.Call(method, one, two);
在最后一行,我得到错误:
System.ArgumentException: 'Expression of type 'System.Int32' cannot be used for parameter of type 'System.Linq.Expressions.Expression' of method 'System.Linq.Expressions.BinaryExpression GreaterThan(System.Linq.Expressions.Expression, System.Linq.Expressions.Expression)''
我想做的是通过在运行时动态选择Expression
中的方法来构建lambda函数。在这里,方法名称将指的是一些根据表达式方法与数字(或字符串)进行比较的方法。
答案 0 :(得分:1)
什么是动态的?操作值(即“一个”和“两个”的类型)?还是操作的类型(“ GreaterThan”,“ LessThen”)?
如果是前者,则无需执行任何操作,因为表达式生成器会处理它。
在
Expression.GreaterThan(Expression.Constant(1), Expression.Constant(2));
和
Expression.GreaterThan(Expression.Constant("Some"), Expression.Constant("text"));
将自动选择适当的大于int和字符串运算符。
如果要使用后者,即动态选择操作,则需要编写
var expr = method.Invoke(null, new object[] { one, two });
这意味着您需要调用expression方法来获取GreaterThan表达式,从而产生与编写Expression.GreaterThan(one, two)
相同的结果。
在表达式方法上调用Expression.Call
类似于创建表达式以创建表达式。
答案 1 :(得分:0)
我认为您应该避免在此处使用反射,而应使用 switch 进行构建。使用这种方法可以获取强类型的所有好处。以https://www.codeproject.com/Articles/1079028/Build-Lambda-Expressions-Dynamically为例。