5

My knowledge of Lambda expressions is a bit shaky, while I can write code that uses Lambda expressions (aka LINQ), I'm trying to write my own method that takes a few arguments that are of type Lambda Expression.

Background: I'm trying to write a method that returns a Tree Collection of objects of type TreeItem from literally ANY other object type. I have the following so far:

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

...which can be called via...

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

I could replace the Expressions with string values, and just use reflection, but I'm trying to avoid this as I want to make it strongly typed.

My reasons for doing this is that I have a control that accepts a List of type TreeItem, whereas I have dozens of different types that are all in a tree like structure, and don't want to write seperate conversion methods for each type (trying to adhere to the DRY principle).

Am I going about this the right way? Is there a better way of doing this perhaps?

1 Answer 1

7

There's no such type as "lambda expression". A lambda expression can either be converted into a compatible delegate type, or an expression tree.

Your existing method signature uses expression trees - but it's not at all clear that it really needs to. Try the delegate form (with a few parameter name changes):

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

Then you can do something like this:

foreach (T item in items)
{
    string id = idSelector(item);
    string text = textSelector(item);
    IList<T> children = childPropertySelector(item);
    // Do whatever you need here
}
Sign up to request clarification or add additional context in comments.

1 Comment

That's brilliant! Just what I was after, thank you soo much! Note the expressions can be converted to the delegates like so: Func<T, IList<T>> childFunc = childProperty.Compile(); but like you said there's no need to, just pass in the Func<T, TProp> delegate type instead, cheers!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.