代码之家  ›  专栏  ›  技术社区  ›  Jeff

ExpressionVisitor.Visit做什么?

  •  6
  • Jeff  · 技术社区  · 14 年前

    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 回复  |  直到 14 年前
        1
  •  3
  •   codekaizen    14 年前

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

    至于用法:

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