如其他答案所示,您有两个表达式,两个表达式中都有一个名为y
的参数。这些并不自动相关。
要正确编译您的表达式,您需要指定两个源表达式的参数:
Expression<Func<string, bool>> e1 = (y => y.Length > 0);
Expression<Func<string, bool>> e2 = (y => y.Length < 5);
var e3 = Expression.And(e1.Body, e2.Body);
var e4 = Expression.Lambda<Func<string, string, bool>>(e3, new[]
);
Func<string, string, bool> compiledExpression = e4.Compile();
bool result = compiledExpression("Foo", "Foo");
当然,您希望有一个将两个表达式合并为仅使用一个参数的表达式。您可以按以下方式重建这些表达式:
ParameterExpression param = Expression.Parameter(typeof(string), "y");
var lengthPropertyExpression = Expression.Property(param, "Length");
var e1 = Expression.GreaterThan(lengthPropertyExpression, Expression.Constant(0));
var e2 = Expression.LessThan(lengthPropertyExpression, Expression.Constant(5));
var e3 = Expression.AndAlso(e1, e2);
var e4 = Expression.Lambda<Func<string, bool>>(e3, new[] { param });
Func<string, bool> compiledExpression = e4.Compile();
bool result = compiledExpression("Foo");
关于你的评论,你不想重新构建表达式,而是在现有表达式的主体和参数上进行操作:可以使用ExpressionRewriter和Replacing the parameter name in the Body of an Expression中的 AndAlso
来实现。
Expression<Func<string, bool>> e1 = (y => y.Length > 0);
Expression<Func<string, bool>> e2 = (z => z.Length < 10);
var e3 = ParameterReplacer.AndAlso<string>(e1, e2);
Func<string, bool> compiledExpression = e3.Compile();
bool result = compiledExpression("Foo");
e1
和e2
进行逻辑与操作,并且作用于同一个输入参数吗? - CodeCastere2
中使用的变量y
没有被定义 - 它可能与e1
中的变量同名,但它们并不匹配。 - Charles Magery
参数引用同一个参数。请注意评论中的“和”字。不用谢。 - CodeCaster