2010-07-05 16 views
6

Zanim ktoś wykrzyknie odpowiedź, przeczytaj to pytanie.Co robi funkcja ExpressionVisitor.Visit <T>?

Jaki jest cel tej metody w .NET 4.0 za ExpressionVisitor:

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

Moje pierwsze przypuszczenie co do celów niniejszej metody było to, że byłoby odwiedzić każdy węzeł w każdym drzewie określonym przez nodes parametr i przepisać drzewo, używając wyniku funkcji elementVisitor.

Nie wydaje się, żeby tak było. Właściwie ta metoda wydaje się robić trochę więcej niż nic, chyba że czegoś tu brakuje, co, jak podejrzewam, jestem ...

Próbowałem użyć tej metody w moim kodzie i gdy wszystko nie działało. zgodnie z oczekiwaniami, ja reflectored metody i stwierdził:

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

więc gdzie by ktoś rzeczywiście iść na temat korzystania z tej metody? Czego tu mi brakuje?

Dzięki.

Odpowiedz

3

Wygląda mi to na wygodną metodę zastosowania aribitracyjnej funkcji transformacji do drzewa wyrażeń i zwrócenia wynikowego przekształconego drzewa lub oryginalnego drzewa, jeśli nie ma żadnych zmian.

Nie widzę, jak to się różni od wzorca, który odwiedzający standardowego wyrażenia, z wyjątkiem korzystania z typu gościem, korzysta z funkcji.

Co do użycia:

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

Nie wyjaśnić, jak oczekuje się zachowywać i dlaczego zatem uważasz, że robi niewiele więcej niż nic.

+1

Oczekiwałbym, że odwiedziłby całe drzewo w addLambdaExpression, a nie tylko sam dodałLambdaExpression. – Jeff

+0

W takim przypadku będziesz chciał dziedziczyć niestandardowy typ z ExpressionVisitor i obsługiwać NodeType.Lambda w metodzie Visit(). – codekaizen