Define part of an Expression as a variable in c#

后端 未结 4 512
有刺的猬
有刺的猬 2020-12-19 10:49

I have following code:

public class MyClass
{
   Expression> Criteria {get; set;}
}
public class Customer
{
   //..
   publ         


        
4条回答
  •  囚心锁ツ
    2020-12-19 11:18

    You can use the following helper functions (one could probably give them a better names, but that's not essential):

    public static class ExpressionUtils
    {
        public static Expression> Bind(this Expression> source, Expression> resultSelector)
        {
            var body = new ParameterExpressionReplacer { source = resultSelector.Parameters[0], target = source.Body }.Visit(resultSelector.Body);
            var lambda = Expression.Lambda>(body, source.Parameters);
            return lambda;
        }
    
        public static Expression> ApplyTo(this Expression> source, Expression> innerSelector)
        {
            return innerSelector.Bind(source);
        }
    
        class ParameterExpressionReplacer : ExpressionVisitor
        {
            public ParameterExpression source;
            public Expression target;
            protected override Expression VisitParameter(ParameterExpression node)
            {
                return node == source ? target : base.VisitParameter(node);
            }
        }
    }
    

    Let see how the sample expression

    c.Criteria = x => x.Name.StartsWith("SomeTexts");
    

    can be built from the two different parts.

    If you have

    Expression> e = x => x.Name;
    

    then

    c.Criteria = e.Bind(x => x.StartsWith("SomeTexts"));
    

    or if you have this instead

    Expression> e = x => x.StartsWith("SomeTexts");
    

    then

    c.Criteria = e.ApplyTo((Customer x) => x.Name);
    

    If you have both expressions, then you can use any of the two functions, since a.Bind(b) is equivalent to b.ApplyTo(a).

提交回复
热议问题