2010-01-27 44 views
0
public static IEnumerable<UIElement> Traverse(this UIElementCollection source) 
    { 
     source.OfType<Grid>().SelectMany(v => Traverse(v.Children)); 
     //This is the top level. 
     foreach (UIElement item in source) 
     { 
      yield return item; 
     } 
    } 

這不會遞歸地返回任何東西。我一直在房子周圍。 Linq鏈應該回調函數/擴展方法,但從來沒有。據我所知,線路什麼也不做。遞歸Linq函數和收益

+1

「圍繞房屋」是什麼意思?這是英國俚語嗎? – 2010-01-27 15:10:24

+1

俚語:嘗試尋找無處不在,找不到我需要的東西。 – DavidA 2010-02-02 14:00:53

回答

0
public static IEnumerable<UIElement> Traverse(this UIElementCollection source) 
    { 
     //This is the top level. 
     foreach (UIElement item in source.OfType<Grid>().SelectMany(v => Traverse(v.Children)).Concat(source.Cast<UIElement>())) 
     { 
      yield return item; 
     } 
    } 

這所期望的結果,不知道它是最佳的,但!

2

你沒有做任何事情與表達式的結果也可能是懶惰的評價不強制執行。如果你真的想忽略表達式的結果,至少應該在最後添加ToArray();)這應該強制執行評估並遞歸地調用你的Traverse函數。

博的解決方案的優勢(前提就是你真正想要的,因爲它不是返回一個不同的結果,你最初的一個),是實際評估的責任轉移到遍歷方法的客戶端。因爲在你的情況下,這些都是內存查詢,但這並不是什麼大不了的,但如果這些是數據庫查詢,那麼將ToArray放在某處會有更顯着的性能損失(實際數據庫查詢的計數)。

+0

我對你很友善,因爲表達不被評估。我需要它來評估。 Var t =在開始時可能? – DavidA 2010-01-27 14:43:53

+0

變種t是不夠的,實際上並沒有迭代它的地方,或ToArray的(),它仍然無法評價執行評估;) – 2010-01-27 14:47:43

+0

好explination因此獲得一些積分! ToArray強制執行標記我的事實,我需要強制它。所以最後使用了concat並將表達式轉儲到了for循環結構中。 – DavidA 2010-01-27 15:09:04

2

遞歸調用永遠不會執行,因爲你永遠不使用的SelectMany結果。 可以使用此法懶惰,讓需要通過 的SelectMany結果與電流源相結合,當客戶進行評估。或許,這樣的事情會做的工作(未測試):

public static IEnumerable<UIElement> Traverse(this UIElementCollection source) 
{ 
    var recursive_result = source.OfType<Grid>().SelectMany(v => Traverse(v.Children)); 
    return recursive_result.Concat(source.Cast<UIElement>()); 
} 
+0

這讓我走在路上! – DavidA 2010-01-27 15:09:36