2010-07-05 4 views
6

Antes de que alguien grite la respuesta, por favor lea la pregunta.¿Qué ExpressionVisitor.Visit <T> hacer?

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 conjetura en cuanto a la finalidad de este método era que iba a visitar cada nodo en cada árbol especificado por el nodes Parametrizar y reescribir 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 falta algo aquí, que sospecho fuertemente que soy ...

Traté de usar este método en mi código y cuando las cosas no funcionaron como era de esperar, reflejé 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, ¿de dónde iba a hacer alguien para utilizar este método? ¿Que me estoy perdiendo aqui?

Gracias.

Respuesta

3

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

No puedo ver cómo esto es diferente de un patrón que un visitante de expresión estándar, a excepción de usar un tipo de visitante, usa una función.

cuanto a 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 explicar cómo se espera que se comporte y por lo tanto cree que no hace más que nada.

+1

Hubiera esperado que visitara todo el árbol en addLambdaExpression, no solo addLambdaExpression. – Jeff

+0

En ese caso, querrá heredar un tipo personalizado de ExpressionVisitor y manejar NodeType.Lambda en el método Visit(). – codekaizen