请帮助解决以下问题:
public class TestParent
{
public int Number { get; set; }
}
public class Test
{
public TestParent Parent { get; set; }
}
class Program
{
static void Main(string[] args)
{
Expression<Func<TestParent, bool>> parentExpression = x => x.Number == 10;
Expression<Func<Test, TestParent>> testExpression = x => x.Parent;
var test = new Test {Parent = new TestParent {Number = 10}};
Expression<Func<Test, bool>> composedExpression = ?; // x => x.Parent.Number == 10
bool result = composedExpression.Compile()(test);
if (result)
{
Console.WriteLine("Test passed!");
}
}
}
答案 0 :(得分:3)
我们可以为这样的表达式创建Compose
方法:
public static Expression<Func<TFirstParam, TResult>>
Compose<TFirstParam, TIntermediate, TResult>(
this Expression<Func<TFirstParam, TIntermediate>> first,
Expression<Func<TIntermediate, TResult>> second)
{
var param = Expression.Parameter(typeof(TFirstParam), "param");
var newFirst = first.Body.Replace(first.Parameters[0], param);
var newSecond = second.Body.Replace(second.Parameters[0], newFirst);
return Expression.Lambda<Func<TFirstParam, TResult>>(newSecond, param);
}
这是使用以下帮助器方法将一个表达式的所有实例替换为另一个:
public static Expression Replace(this Expression expression,
Expression searchEx, Expression replaceEx)
{
return new ReplaceVisitor(searchEx, replaceEx).Visit(expression);
}
internal class ReplaceVisitor : ExpressionVisitor
{
private readonly Expression from, to;
public ReplaceVisitor(Expression from, Expression to)
{
this.from = from;
this.to = to;
}
public override Expression Visit(Expression node)
{
return node == from ? to : base.Visit(node);
}
}
这允许你写:
Expression<Func<Test, bool>> composedExpression =
testExpression.Compose(parentExpression);
答案 1 :(得分:0)
我认为您正在尝试创建一个新表达式,该表达式包含现在在两个单独的表达式parentExpression
和testExpression
中定义的逻辑。
不幸的是,你不能轻易地组合这样的表达式(不分解表达式和使用内部表达式主体),因为表达式的参数不同,你必须从两个表达式的内容手动创建表达式。你不能按原样使用这两个表达式,并将它们组合起来。
您可以编译这两个表达式,并在新表达式中使用它们。这将是这样的。但要注意,composedExpression
只不过是对已编译表达式的调用。它将不包含现在在其他两个表达式中定义的逻辑。
Expression<Func<TestParent, bool>> parentExpression = x => x.Number == 10;
Expression<Func<Test, TestParent>> testExpression = x => x.Parent;
var parentExpressionCompiled = parentExpression.Compile();
var testExpressionCompiled = testExpression.Compile();
var test = new Test {Parent = new TestParent {Number = 10}};
Expression<Func<Test, bool>> composedExpression = x => parentExpressionCompiled(testExpressionCompiled(x));
bool result = composedExpression.Compile()(test);
if (result) {
Console.WriteLine("Test passed!");
}
答案 2 :(得分:0)
完成这项工作:
var composedExpression = testExpression.Combine(parentExpression, true);
其中Combine实施来自:Combining two lambda expressions in c#