2010-03-29 23 views
5

Moja wiedza na temat wyrażeń lambdy jest nieco chwiejna, podczas gdy ja mogę napisać kod wykorzystujący wyrażenia Lambda (aka LINQ), próbuję napisać własną metoda, która pobiera kilka argumentów typu Lambda Expression.Jak przetwarzać wyrazy Lambda przekazane jako argument do metody - C# .NET 3.5

Tło: Próbuję napisać metodę, która zwraca Tree Collection z obiektów typu TreeItem z dosłownie DOWOLNEGO innego typu obiektu. Mam następujący tej pory:

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

... która może być wywołana przez ...

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

mógłbym wymienić wyrażeń z ciągów znaków, i po prostu użyć refleksji, ale jestem staram się tego uniknąć, ponieważ chcę, aby był mocno napisany.

Moje powody, dla których to robię, to to, że mam kontrolę, która akceptuje listę typu TreeItem, podczas gdy ja mam dziesiątki różnych typów, które są wszystkie w strukturze drzewa i nie chcę pisać oddzielnych metod konwersji dla każdy typ (starając się przestrzegać zasady DRY).

Czy podążam tą właściwą drogą? Czy jest na to lepszy sposób?

Odpowiedz

7

Nie ma takiego typu jak "wyrażenie lambda". Wyrażenie lambda można przekonwertować na zgodny typ delegata lub na expression tree.

Twój istniejący podpis metody używa drzewek wyrażeń - ale nie jest wcale jasne, czy to naprawdę konieczne. Spróbuj formularz delegata (z kilkoma zmianami nazwa parametru):

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 

Następnie można zrobić coś takiego:

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

To genialne! Właśnie o co mi chodziło, dziękuję bardzo za dużo! Zauważ, że wyrażenia mogą być konwertowane na delegatów w taki sposób: Func > childFunc = childProperty.Compile(); ale jak już powiedziałeś, nie ma potrzeby, po prostu przepisz w stylu delegata Func , okrzyki! –

Powiązane problemy