代码之家  ›  专栏  ›  技术社区  ›  David

规范模式-使用lambdas(C#)创建复合规范

  •  2
  • David  · 技术社区  · 14 年前

    如果我有一个定义为表达式的规范,如下所示:

    public Expression<Func<Foo, bool>> IsSuperhuman = 
      x => x.CanFly && x.HasXRayVision;
    

    我想定义另一个规范“IsSuperheroine”,逻辑是“is superman And is female”,如何在新规范中重用现有规范?

    2 回复  |  直到 14 年前
        1
  •  1
  •   Mant101    14 年前

    你退房了吗 predicate builder 在LinqKit?它通过让你和或表达式在一起来建立表达式。

        2
  •  1
  •   Thomas Levesque    14 年前

    Expression<Func<Foo, bool>> IsSuperhuman = x => x.CanFly && x.HasXRayVision;
    
    Expression<Func<Foo, bool>> IsSuperheroine = AndAlso(IsSuperhuman, x => x.IsFemale);
    
    ...
    
    public static Expression<Func<T, TResult>> AndAlso<T, TResult>(Expression<Func<T, TResult>> expr1, Expression<Func<T, TResult>> expr2)
    {
        var arg = Expression.Parameter(typeof(T), expr1.Parameters[0].Name);
        var andExpr = Expression.AndAlso(
            ReplaceParameter(expr1.Body, expr1.Parameters[0], arg),
            ReplaceParameter(expr2.Body, expr2.Parameters[0], arg));
        return Expression.Lambda<Func<T, TResult>>(andExpr, arg);
    }
    
    public static Expression ReplaceParameter(Expression expr, ParameterExpression oldParam, ParameterExpression newParam)
    {
        return new ReplaceParameterVisitor(oldParam, newParam).Visit(expr);
    }
    
    internal class ReplaceParameterVisitor : ExpressionVisitor
    {
        private ParameterExpression _oldParam;
        private ParameterExpression _newParam;
    
        public ReplaceParameterVisitor(ParameterExpression oldParam, ParameterExpression newParam)
        {
            _oldParam = oldParam;
            _newParam = newParam;
        }
    
        protected override Expression VisitParameter(ParameterExpression node)
        {
            if (node == _oldParam)
                return _newParam;
            return node;
        }
    }
    

    这可能不是最简单的方法,但它的工作。。。

    推荐文章