专注收集记录技术开发学习笔记、技术难点、解决方案
网站信息搜索 >> 请输入关键词:
您当前的位置: 首页 > WPF

Expression心得之一:合并LambdaExpression

发布时间:2011-06-23 13:53:10 文章来源:www.iduyao.cn 采编人员:星星草
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,问题解决。

 测试代码

友情提示:
信息收集于互联网,如果您发现错误或造成侵权,请及时通知本站更正或删除,具体联系方式见页面底部联系我们,谢谢。

其他相似内容:

热门推荐: