2010-03-29 710 views
5

我對Lambda表達式的瞭解有點不穩定,但我可以編寫使用Lambda表達式(又名LINQ)的代碼,我試圖寫我自己的方法,該方法需要一些類型爲Lambda Expression的參數。如何處理Lambda表達式作爲參數傳入方法 - C#.NET 3.5

背景:我試圖編寫一個方法,從字面上返回任意其他對象類型的TreeItem對象的樹集合。我見到目前爲止如下:

public class TreeItem 
{ 
    public string Id { get; set; } 
    public string Text { get; set; } 

    public TreeItem Parent { get; protected set; } 

    public IList<TreeItem> Children 
    { 
     get 
     { 
      // Implementation that returns custom TreeItemCollection type 
     } 
    } 

    public static IList<TreeItem> GetTreeFromObject<T>(IList<T> items, 
     Expression<Func<T, string>> id, 
     Expression<Func<T, string>> text, 
     Expression<Func<T, IList<T>>> childProperty) where T : class 
    { 
     foreach (T item in items) 
     { 
      // Errrm!?? What do I do now? 
     } 

     return null; 
    } 
} 

...這可以通過被稱作......

IList<TreeItem> treeItems = TreeItem.GetTreeFromObject<Category>(
    categories, c => c.Id, c => c.Name, c => c.ChildCategories); 

我可以用字符串值替換表達式,只是使用反射,但我試圖避免這一點,因爲我想讓它強制輸入。

我這樣做的原因是我有一個控件接受一個TreeItem類型的列表,而我有幾十個不同的類型,它們都像結構樹一樣在樹中,並且不想編寫單獨的轉換方法每種類型(試圖堅持DRY原則)。

我對此有何看法?也許有更好的方式來做到這一點?

回答

7

沒有「lambda表達式」這樣的類型。一個lambda表達式可以轉換爲兼容的委託類型,或者一個expression tree

您現有的方法簽名使用表達式樹 - 但它完全不清楚它確實需要。嘗試委託形式(有一些參數名稱更改):

public static IList<TreeItem> GetTreeFromObject<T>(IList<T> items, 
    Func<T, string> idSelector, 
    Func<T, string> textSelector, 
    Func<T, IList<T>> childPropertySelector) where T : class 

然後,你可以做這樣的事情:

foreach (T item in items) 
{ 
    string id = idSelector(item); 
    string text = textSelector(item); 
    IList<T> children = childPropertySelector(item); 
    // Do whatever you need here 
} 
+0

這是輝煌!正是我所追求的,非常感謝你!請注意,表達式可以轉換爲委託,如下所示:Func > childFunc = childProperty.Compile();但就像你說的那樣,不需要傳遞Func 委託類型,而是歡呼! – 2010-03-29 12:02:48

相關問題