Nested lambda for use with Fluent Interface

Given the following types:

class Parent { List<Child> Children {get;set;}}
class Child {List<Child> GrandChildren {get;set;}}

class Helper<TEntity> {List<string> Properties {get;set;}}

      

And given the following methods in Helper ...

public Helper AddProps<TEntity, TProp>(Expression<Func<TEntity, TProp>> exp)
{
     this.Properties.Add(GetPropInfo(exp).Name);
}

public PropertyInfo GetPropInfo(Expression<Func<TEntity, TProp>> exp)
{
     return (PropertyInfo)((MemberExpression)(expression.Body)).Member;
}

      

I can do it:

Helper<Parent> myHelper = new Helper<Parent>();
myHelper.AddProps(x => x.Children);

      

The string listing "Properties" in myHelper will then contain the value "Children", the name of the property passed through the expression.

Now I want to do the same, only with the ability to reflect the type hierarchy.

Will it look like this?

x => x.Children { xx => xx.GrandChildren }

      

Or is it possible and what will be involved? I've seen nested lambda before, but don't know what I was involved.

Thanks in advance!

EDIT

There seems to be some confusion, so I'll try to clarify. I want to be able to create a string that looks like "Object.SubObject.SubSubObject" using lambda expressions and method chaining. My example does this, but only for one level of depth (class property). I want to do this to go to any depth.

For example, I would like to use lambda expressions with a fluid interface that would look something like this.

AddProps (x => x.Children) .AddProps (xx => xx.GrandChildren) and this will add "Children.GrandChildren" to the list of "Properties" strings.

+2


source to share


2 answers


I ended up using an alternative solution that worked well enough. He uses this new class ...

public class PartBuilder
{
    private List<string> Parts;

    /// <summary>
    /// Gets a dot delimited string representing the parts
    /// </summary>
    public string Value
    {
        get
        {
            return string.Join(".", this.Parts.ToArray());
        }
    }

    /// <summary>
    /// Creates a new PartBuilder
    /// </summary>
    private PartBuilder()
    {
        this.Parts = new List<string>();
    }


    /// <summary>
    /// Creates a new PartBuilder
    /// </summary>
    public static PartBuilder Create()
    {
        return new PartBuilder();
    }


    /// <summary>
    /// Gets a property name from an expression
    /// </summary>
    public PartBuilder AddPart<TEntity, TProp>(Expression<Func<TEntity, TProp>> expression)
    {
        PropertyInfo prop = (PropertyInfo)((MemberExpression)(expression.Body)).Member;
        this.Parts.Add(prop.Name);

        return this;
    }
}

      

Now that I have this new class, I can do this ...



string typeHierarchy = PartBuilder.Create()
                         .AddPart((Parent p) => p.Children)
                         .AddPart((Child pp) => pp.GrandChildren)
                         .Value;

      

The variable "typeHierarchy" is now set to "Children.GrandChildren".

It's not as elegant as I would have hoped, but it's kind of safe and easy to use.

0


source


This can make things easier if the AddProps method is shared rather than the entire helper class.

So you can get this code:

var helper = new Helper();
helper.AddProps<Parent>(x => x.Children);
helper.AddProps<Child>(x => x.GrandChildren);

      



You can also store more than just the property name so you know what type the property belongs to. I think you can have a dictionary to store properties for each type you register.

PS Knowing why you want to do this can help the SO community better answer your question.

+2


source







All Articles