Expression经验之一:合并LambdaExpression

有时我们会碰到这样的状况,就是要把两个LambdaExpression合并起来变成一个LambdaExpression.

例如我们有如下两个用来筛选DataRow的表达式:


Expression<Func<DataRow, bool>> exp1 = r => r["name"].ToString() == "Rose";
Expression<Func<DataRow, bool>> exp2 = r => (int)r["age"] > 20;

 

那现在我们想即根据name又根据age来筛选呢,也就是说我们想要这样的表达式:

Expression<Func<DataRow, bool>> exp1 = r => r["name"].ToString() == "Rose" && (int)r["age"]>20;

很容易想到,可以用Expression.AndAlso来做,即

var newExp = Expression.Lambda(Expression.AndAlso(exp1.Body, exp2.Body),
Expression.Parameter(typeof (DataRow), "r"));

一切看起来很美好;p

但是接下来我们试图去compile时就会出错了,

 

这个错误就是由于两个LambdaExpression的Body引用的是两个不同的parameter instance,尽管parameter 的名字看起来是一样的。关于这个错误这篇stackoverflow文章说的很好:http://stackoverflow.com/questions/10613514/how-can-i-combine-two-lambda-expressions-without-using-invoke-method

并且这篇文章也很出了一个基于ExpressionVisitor的解决方案,这个解决方案很棒并且切中了要点。但我觉得实现不是很直观也,我的另一个解决方案是实现别一个ParameterReplacementVisitor。

代码如下:

public class ParameterReplacementVisitor : ExpressionVisitor
        {
            private readonly ParameterExpression _parameter;

            public ParameterReplacementVisitor(ParameterExpression parameter)
            {
                _parameter = parameter;
            }

            public ParameterExpression Parameter
            {
                get { return _parameter; }
            }

            protected override Expression VisitParameter(ParameterExpression node)
            {
                if (node.Name == _parameter.Name)
                {
                    return _parameter;
                }

                return base.VisitParameter(node);
            }
        }

 

这样很容易理解,并且采用的策略很简单,就是根据Parameter Name来把parameter 统一替换成给定的parameter,问题解决。

 测试代码

转载于:https://www.cnblogs.com/zzagly/p/5849491.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值