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.
source to share
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.
source to share
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.
source to share