2010-07-05 10 views
6

Prima che qualcuno gridi, rispondi alla domanda.Che cosa fa ExpressionVisitor.Visit <T> Do?

Qual è lo scopo del metodo in ExpressionVisitor NET 4.0 del:

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

La mia prima risposta in merito alla finalità di questo metodo è che sarebbe visitare ogni nodo in ogni albero specificato dal nodes parametrizzare e riscrivere l'albero usando il risultato della funzione elementVisitor.

Questo non sembra essere il caso. In realtà questo metodo sembra fare un po 'più di niente, a meno che manchi qualcosa qui, che sospetto fortemente di essere ...

Ho provato a usare questo metodo nel mio codice e quando le cose non hanno funzionato come previsto, ho riflettuto il metodo e ho trovato:

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

Quindi, dove qualcuno dovrebbe effettivamente utilizzare questo metodo? Cosa mi manca qui?

Grazie.

risposta

3

Mi sembra un metodo pratico per applicare una funzione di trasformazione aribrizionale a un albero di espressioni e restituire l'albero trasformato risultante o l'albero originale se non vi è alcun cambiamento.

Non riesco a vedere come questo sia diverso da un modello che un visitatore di espressioni standard, tranne che per l'utilizzo di un tipo di visitatore, utilizza una funzione.

Per quanto riguarda l'utilizzo:

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

Non spiegare come ci si aspettava comportarsi e perché, pertanto si pensa che fa poco più di niente.

+1

Mi sarei aspettato che visitasse l'intero albero in addLambdaExpression, non solo addLambdaExpression. – Jeff

+0

In tal caso, si desidera ereditare un tipo personalizzato da ExpressionVisitor e gestire il NodeType.Lambda nel metodo Visit(). – codekaizen