【发布时间】:2017-05-17 10:08:08
【问题描述】:
我在动态或直接调用Expression.GreaterThanOrEqual 时会出现不同的行为。
using System;
using System.Linq.Expressions;
using System.Reflection;
namespace ExpressionExample
{
class Program
{
static void Main(string[] args)
{
// Build expression head.
ParameterExpression param = Expression.Parameter(typeof(MyObj), "x");
MemberExpression property = Expression.Property(param, "MyProperty");
int value = 1;
// Build expression body.
MethodInfo greaterThanOrEqual = typeof(Expression)
.GetMethod("GreaterThanOrEqual",
new[] { typeof(Expression), typeof(Expression) });
Expression valueExpr = Expression.Convert(Expression.Constant(value),
property.Type);
// Dynamic Call
//var expressionBody = Expression.Call(null, greaterThanOrEqual, property,
valueExpr);
// Direct Call
var expressionBody = Expression.GreaterThanOrEqual(property, valueExpr);
// Make Lambda.
Expression.Lambda<Func<MyObj, bool>>(expressionBody, param);
}
}
class MyObj
{
public int MyProperty { get; set; }
}
}
为了简单起见,我将代码断章取义。最后的 Lambda 稍后在 Queryable 的 where 方法中使用。直接调用工作正常并给出了预期的结果。然而,动态调用会引发System.ArgumentException,表示System.Int32 不能用作BinaryExpression GreaterThanOrEqual 的参数。这实际上是我之前转换值的原因,这也是直接调用所必需的。
这里有什么不同?我怎样才能让动态调用起作用?
【问题讨论】:
-
不同的是,你所说的动态调用根本不是调用。为了为您提供解决方案,您需要提供需要动态调用的示例用例。
-
我用一个最小且可运行的例子更新了这个问题。
-
好的,但这不是我需要的。我知道它是可重现的,但找不到动态调用的实际需求(用例)来回答您的第二个问题(如何使其工作)。
-
我正在开发一个由 json 控制的过滤器(表达式树)。因此,您向 API 发送请求以获取实体列表。响应包含的实体由 (json) 过滤器确定。过滤器是一个包含布尔代数的树形式的公式。目前,等式表达式被分离成它们自己的方法。现在我想称他们只有 MethodInfo。
标签: c# entity-framework reflection lambda expression-trees