2010-03-29 13 views
5

Mi conocimiento de las expresiones Lambda es un poco inestable, mientras que puedo escribir código que utiliza expresiones Lambda (aka LINQ), estoy tratando de escribir mi propio método que toma algunos argumentos que son del tipo Lambda Expression.Cómo procesar expresiones Lambda pasado como argumento en el método - C# .NET 3.5

Antecedentes: Estoy tratando de escribir un método que devuelva una Colección de árbol de objetos de tipo TreeItem de literalmente CUALQUIER otro tipo de objeto. Tengo el siguiente hasta el momento:

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

... que se puede llamar a través de ...

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

que podrían reemplazar a las expresiones con valores de cadena, y sólo tiene que utilizar la reflexión, pero estoy tratando de evitar esto, ya que quiero hacerlo fuertemente tipado.

Mis razones para hacer esto es que tengo un control que acepta una lista de tipo TreeItem, mientras que tengo docenas de tipos diferentes que están todos en una estructura tipo árbol, y no quiero escribir métodos de conversión separados para cada tipo (tratando de cumplir con el principio DRY).

¿Voy por esto de la manera correcta? ¿Hay una mejor manera de hacer esto quizás?

Respuesta

7

No existe el tipo de expresión "lambda". Una expresión lambda puede convertirse en un tipo de delegado compatible o expression tree.

Su firma de método existente usa árboles de expresiones, pero no está del todo claro que realmente lo necesite. Pruebe la forma delegado (con algunos cambios de nombre de parámetro):

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 

entonces usted puede hacer algo como esto:

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

Eso es brillante! Justo lo que estaba buscando, ¡muchas gracias! Tenga en cuenta que las expresiones se pueden convertir a los delegados de la siguiente manera: Func > childFunc = childProperty.Compile(); pero como dijiste que no es necesario, solo pasa el tipo de delegado Func , ¡gracias! –