2010-03-29 5 views
5

La mia conoscenza delle espressioni Lambda è un po 'instabile, mentre posso scrivere codice che usa espressioni Lambda (ovvero LINQ), sto provando a scrivere da solo metodo che accetta alcuni argomenti di tipo Lambda Expression.Come elaborare le espressioni Lambda Passate come argomento nel metodo - C# .NET 3.5

Background: Sto provando a scrivere un metodo che restituisca una Tree Collection di oggetti di tipo TreeItem da QUALSIASI altro tipo di oggetto. Ho il seguente finora:

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

... che può essere chiamato via ...

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

potrei sostituire le espressioni con valori di stringa, e basta usare la riflessione, ma sono cercando di evitare questo perché voglio farlo fortemente battuto a macchina.

Le mie ragioni per fare questo è che ho un controllo che accetta un elenco di tipo TreeItem, mentre ho dozzine di tipi diversi che sono tutti in una struttura ad albero, e non voglio scrivere metodi di conversione separati per ogni tipo (cercando di aderire al principio SECCO).

Sto andando su questo nel modo giusto? C'è un modo migliore per farlo forse?

risposta

7

Non esiste un tipo di "espressione lambda". Un'espressione lambda può essere convertita in un tipo di delegato compatibile oppure in expression tree.

La firma del metodo esistente utilizza gli alberi di espressione, ma non è affatto chiaro che sia necessario. Prova la forma delegato (con un paio di cambi di nome parametro):

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 

allora si può fare qualcosa di simile:

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

Questo è brillante! Proprio quello che stavo cercando, grazie mille! Nota: le espressioni possono essere convertite in delegati in questo modo: Func > childFunc = childProperty.Compile(); ma come hai detto tu non è necessario, basta passare il tipo di delegazione Func invece, evviva! –

Problemi correlati