【问题标题】:What does ExpressionVisitor.Visit<T> Do?ExpressionVisitor.Visit<T> 做什么?
【发布时间】:2010-07-05 17:27:14
【问题描述】:

在有人喊出答案之前,请仔细阅读问题。

.NET 4.0 的 ExpressionVisitor 中方法的用途是什么:

public static ReadOnlyCollection<T> Visit<T>(ReadOnlyCollection<T> nodes, Func<T, T> elementVisitor)

我对这个方法的目的的第一个猜测是它会访问nodes 参数指定的每棵树中的每个节点,并使用elementVisitor 函数的结果重写树。

情况似乎并非如此。实际上,这种方法似乎比什么都不做,除非我在这里遗漏了一些东西,我强烈怀疑我是......

我尝试在我的代码中使用此方法,但当事情没有按预期进行时,我反映了该方法并发现:

public static ReadOnlyCollection<T> Visit<T>(ReadOnlyCollection<T> nodes, Func<T, T> elementVisitor)
{
    T[] list = null;
    int index = 0;
    int count = nodes.Count;
    while (index < count)
    {
        T objA = elementVisitor(nodes[index]);
        if (list != null)
        {
            list[index] = objA;
        }
        else if (!object.ReferenceEquals(objA, nodes[index]))
        {
            list = new T[count];
            for (int i = 0; i < index; i++)
            {
                list[i] = nodes[i];
            }
            list[index] = objA;
        }
        index++;
    }
    if (list == null)
    {
        return nodes;
    }
    return new TrueReadOnlyCollection<T>(list);
}

那么有人会在哪里实际使用这种方法呢?我在这里错过了什么?

谢谢。

【问题讨论】:

    标签: linq c#-4.0 expression-trees expressionvisitor


    【解决方案1】:

    在我看来,将任意变换函数应用于表达式树并返回结果变换的树,或者如果没有变化,则返回原始树。

    我看不出这与标准表达式访问者的模式有何不同,除了使用访问者类型之外,它使用函数。

    关于用法:

    Expression<Func<int, int, int>> addLambdaExpression= (a, b) => a + b;
    
    // Change add to subtract
    Func<Expression, Expression> changeToSubtract = e => 
    { 
        if (e is BinaryExpression) 
        { 
            return Expression.Subtract((e as BinaryExpression).Left,
                                       (e as BinaryExpression).Right); 
        }
        else
        {
            return e;
        }
    };  
    
    var nodes = new Expression[] { addLambdaExpression.Body }.ToList().AsReadOnly();
    var subtractExpression = ExpressionVisitor.Visit(nodes, changeToSubtract);
    

    您没有解释您期望它的行为方式以及为什么您认为它几乎没有作用。

    【讨论】:

    • 我原以为它会访问 addLambdaExpression 中的整个树,而不仅仅是 addLambdaExpression 本身。
    • 在这种情况下,您需要从 ExpressionVisitor 继承自定义类型并在 Visit() 方法中处理 NodeType.Lambda。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-28
    • 1970-01-01
    • 2010-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多