假设我有以下课程:
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
。
我想我已经找到答案了。有人可以告诉我这是否合法吗?
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);
}