Вложенная лямбда для использования с плавным интерфейсом


Даны следующие типы:

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

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

И даны следующие методы на хелпере...

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

Строковый список " Properties "на myHelper будет содержать значение" Children", имя свойства, передаваемого через выражение.

То, что я хочу сделать сейчас, - это иметь возможность достичь того же самого, только с возможностью отражать иерархию типов.

Будет ли это выглядеть так ?

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

Или это вообще возможно,и что бы это значило? Я видел вложенные лямбды раньше, но не знаю, что это такое.

Заранее спасибо!

EDIT

Похоже, что есть некоторая путаница, поэтому я попытаюсь прояснить. Я хочу иметь возможность создать строку, которая выглядит как этот " объект.подобъект.SubSubObject " с использованием лямбда-выражений и метода chaining. Мой пример делает это, но только для одного уровня deep (свойство класса). То, что я хочу do-это расширить это, чтобы пойти на любую глубину.

Например, я хотел бы использовать лямбда-выражения с плавным интерфейсом, который выглядел бы примерно так....

AddProps(х => х.Детей).Добавьте капли (xx => XX. внуков), и это добавит "детей.Внуки "в мой список строк "свойства".

2 2

2 ответа:

Может быть проще, если метод AddProps является универсальным, а не всем вспомогательным классом.

Таким образом, вы можете получить следующий код:

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

Вы также можете сохранить не только имя свойства, чтобы знать, к какому типу принадлежит свойство. Я думаю, что вы могли бы иметь словарь для хранения свойств для каждого типа, который вы зарегистрировали.

P.S. знание того, почему вы хотите это сделать, может помочь сообществу SO лучше ответить на ваш вопрос.

В итоге я использовал альтернативное решение, которое работало довольно хорошо. Он использует этот новый класс...

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.внучата". Это не так элегантно, как я надеялся, но это типобезопасно и легко в использовании.