2010-07-05 103 views
6

在有人喊出答案之前,請通讀問題。ExpressionVisitor.Visit <T>是做什麼用的?

什麼方法在.NET 4.0中的ExpressionVisitor目的:

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

那麼有人真的會去哪裏使用這種方法?我在這裏錯過了什麼?

謝謝。

回答

3

它在我看來就像是一種方便的方法,將一個任意的變換函數應用到表達式樹上,並返回結果變換後的樹,如果沒有變化則返回原始樹。

我看不出這是什麼樣的標準表達式訪問者,除了使用訪問者類型之外,它使用一個函數。

至於用法:

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

你不解釋你如何期望它的行爲,爲什麼因此,你認爲它比沒有多一點。

+1

我本來期望它在addLambdaExpression中訪問整個樹,而不僅僅是addLambdaExpression本身。 – Jeff 2010-07-05 18:26:44

+0

在這種情況下,您需要從ExpressionVisitor繼承自定義類型,並在Visit()方法中處理NodeType.Lambda。 – codekaizen 2010-07-05 18:48:38