Как реализовать следующее использование дерева выражений c #? - PullRequest
0 голосов
/ 25 сентября 2019

Предполагая, что у меня есть следующий класс:

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

Как я могу или, если вообще возможно, реализовать метод с использованием дерева выражений так, чтобы он выглядел следующим образом?

Dictionary<string, object> someDictionary = GetDictionary();
Person person = new Person();
person.Set(someDictionary, "someKey", p => p.Name, value => Transform(value));

Так что person.Name будет установлено Transform(value), где value предоставляется словарем?

Я запустил сигнатуру метода расширения, подобного

public static void Set<TValue>(
    this Person person, 
    IDictionary<string, object> dictionary, 
    string key, 
    Expression<Func<Person, TValue>> selector, 
    Expression<Func<object, TValue>> transformer)

Но не особо разбираюсь в том, как его реализовать.
Любая помощь приветствуется.Спасибо.

У меня есть что-то вроде следующего:

public static void Set<TValue>(this Person person, IDictionary<string, object> dictionary, string key, Expression<Func<Person, TValue>> selector, Expression<Func<object, TValue>> transformer)
{
    if (!dictionary.TryGetValue(key, out var value))
    {
        return;
    }

    // more logic to manipulate 'value'...

    var parameterExpression = (ParameterExpression) ((MemberExpression) selector.Body).Expression;
    var delegateExpression = Expression.Lambda<Action<Person>>(
        Expression.Assign(selector.Body, transformer.Body), parameterExpression
    );

    delegateExpression.Compile()(person);
}

Но я не могу понять, как передать value в transformer.

1 Ответ

0 голосов
/ 25 сентября 2019

Я думаю, что получил ответ.Кто-нибудь может сказать мне, законно ли это?

public static void Set<TValue>(this Person person, IDictionary<string, object> dictionary, string key, Expression<Func<Person, TValue>> selector, Expression<Func<object, TValue>> transformer)
{
    if (!dictionary.TryGetValue(key, out var value))
    {
        return;
    }

    var parameterExpression = selector.Parameters.Concat(transformer.Parameters);
    var delegateExpression = Expression.Lambda<Action<Person, object>>(
        Expression.Assign(selector.Body, transformer.Body), parameterExpression
    );

    delegateExpression.Compile()(person, value);
}
...