首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Lambda的Linq表达式:显式指定参数

Lambda的Linq表达式:显式指定参数
EN

Stack Overflow用户
提问于 2014-05-27 12:21:52
回答 1查看 221关注 0票数 1

我想嵌入一个表达式树,例如

代码语言:javascript
复制
Expression<Func<MyObject, double>> expr = (o) => o.Value;

转换为解析器生成的更大的表达式树。但是,参数o已经定义在外部表达式树中。原则上,我必须搜索expr的主体,并从解析的表达式树中用实例替换所有出现的参数。

有建好的路来做这个吗?或者是否有一种方法可以在预先指定参数实例的同时直接生成lambda表达式?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-05-27 12:47:03

您不能直接指示编译器重用您现有的ParameterExpression实例,但是您肯定可以在之后替换它们(实际上是创建新的表达式树)。

内置的ExpressionVisitor在繁重的工作中有很大的帮助;它是一个非op访问者,您可以从它派生来添加所需的功能。在这种情况下,您需要指示它替换ParameterExpression实例,这样您就可以拥有以下内容:

代码语言:javascript
复制
// Sorry for the atrocious formatting, wanted to keep it scrollbar-free
class ParameterReplacementVisitor : ExpressionVisitor
{
    private readonly
    IEnumerable<KeyValuePair<ParameterExpression, ParameterExpression>>
    replacementMap;

    public ParameterReplacementVisitor(
        IEnumerable<KeyValuePair<ParameterExpression, ParameterExpression>> map)
    {
        this.replacementMap = map;
    }

    protected override Expression VisitLambda<T>(Expression<T> node)
    {
        return Expression.Lambda<T>(
            Visit(node.Body),
            node.Parameters.Select(Visit).Cast<ParameterExpression>());
    }

    protected override Expression VisitParameter(ParameterExpression node)
    {
        var replacement = this.replacementMap
                              .Where(p => p.Key == node)
                              .DefaultIfEmpty()
                              .First().Value;
        return base.VisitParameter(replacement ?? node);
    }
}

你可以这样用:

代码语言:javascript
复制
Expression<Func<int, bool>> e1 = i => true;
Expression<Func<int, bool>> e2 = j => false;

Console.WriteLine(e1.Parameters[0] == e2.Parameters[0]); // false

var replacements = new Dictionary<ParameterExpression, ParameterExpression>
{
    { e1.Parameters[0], e2.Parameters[0] }
};

var replacer = new ParameterReplacementVisitor(replacements);
var e3 = replacer.VisitAndConvert(e1, "replacing parameters");

Console.WriteLine(e3.Parameters[0] == e2.Parameters[0]); // true
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23889328

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档