¿Qué hace ExpressionVisitor.Visit ¿Hacer?

c#-4.0 expression-trees expressionvisitor linq

Pregunta

Antes de que alguien grite la respuesta, lea la pregunta.

¿Cuál es el propósito del método en ExpressionVisitor de .NET 4.0?

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

Mi primera suposición sobre el propósito de este método fue que visitaría cada nodo en cada árbol especificado por el parámetro de nodes y reescribiría el árbol usando el resultado de la función elementVisitor .

Esto no parece ser el caso. En realidad, este método parece hacer un poco más que nada, a menos que me esté perdiendo algo aquí, que sospecho que soy ...

Intenté usar este método en mi código y cuando las cosas no funcionaron como se esperaba, reflexioné sobre el método y encontré:

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

Entonces, ¿dónde iría alguien a usar este método? ¿Que me estoy perdiendo aqui?

Gracias.

Respuesta aceptada

Me parece un método conveniente para aplicar una función de transformación aribitraria a un árbol de expresiones y devolver el árbol transformado resultante o el árbol original si no hay ningún cambio.

No puedo ver cómo es diferente de un patrón que un visitante de expresión estándar, excepto por el uso de un tipo de visitante, utiliza una función.

En cuanto al uso:

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

No explica cómo esperaba que se comportara y por qué, por lo tanto, piensa que hace poco más que nada.



Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow