如何实现以下c#表达式树用法?

问题描述 投票:0回答:1

假设我有以下课程:

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

c# expression expression-trees
1个回答
0
投票

我想我已经找到答案了。有人可以告诉我这是否合法吗?

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);
}
© www.soinside.com 2019 - 2024. All rights reserved.