ExpressionVisitor.Visit<T> 是做什么的?

7
在有人喊出答案之前,请仔细阅读问题。.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);
}

那么,有人应该在哪里使用这种方法呢?我错过了什么吗?

谢谢。

1个回答

4

在我看来,这是一种将任意转换函数应用于表达式树并返回结果转换后的树或原始树(如果没有更改)的方便方法。

我认为这与标准表达式访问者模式没有任何区别,除了使用访问者类型外,它使用一个函数。

至于用法:

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);

您没有解释您期望它如何运作,因此您认为它几乎没有任何作用。


1
我本来期望它在addLambdaExpression中访问整个树,而不仅仅是addLambdaExpression本身。 - Jeff
1
在这种情况下,您将希望从ExpressionVisitor继承自定义类型,并在Visit()方法中处理NodeType.Lambda。 - codekaizen
你知道怎么把 subtractExpression 转换回 Expression<Func<int, int, int>> 的机会大吗?我好像找不到一个完整的例子... - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接