嵌套Lambda用于Fluent接口

时间:2009-09-12 04:19:54

标签: c# lambda fluent-interface

考虑以下类型:

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

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

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

我能够这样做:

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

myHelper上的字符串列表“Properties”将包含值“Children”,即通过表达式传递的属性的名称。

我现在要做的是能够实现同样的目标,只能反映类型层次结构。

会是这样的吗?

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

或者甚至是可能的,还会涉及到什么?我以前见过嵌套的lambda,但不知道涉及到什么。

提前致谢!

修改

似乎有一些混乱所以我会试着澄清一下。我希望能够使用lambda表达式和方法链接创建一个看起来像这个“Object.SubObject.SubSubObject”的字符串。我的例子是这样做的,但仅限于一个级别(类的属性)。我想要做的是将其扩展到任何深度。

例如,我想使用具有流畅界面的lambda表达式,看起来像这样....

AddProps(x =&gt; x.Children).AddProps(xx =&gt; xx.GrandChildren),这会将“Children.GrandChildren”添加到我的“属性”字符串列表中。

2 个答案:

答案 0 :(得分:2)

如果AddProps方法是通用的,而不是整个Helper类,它可能会使事情变得更容易。

通过这种方式,您可以拥有以下代码:

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

您可能还希望保留多个属性名称,以便了解该属性属于哪种类型。我想你可以有一个字典来存储你注册的每种类型的属性。

P.S。了解您为什么要这样做可能有助于SO社区更好地回答您的问题。

答案 1 :(得分:0)

我最终使用了一种效果很好的备用解决方案。它使用这个新类......

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

现在我有了这个新课程,我可以这样做......

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

变量“typeHierarchy”现在的值为“Children.GrandChildren”。

它并不像我希望的那样优雅,但它的类型安全且易于使用。