属性select器expression式<Func <T >>。 如何获取/设置选定的属性值
我有一个目标,我想以这样的方式来构build:
var foo = new FancyObject(customer, c=>c.Email); //customer has Email property
我应该如何声明第二个参数?
如何访问选定属性setter / getter的代码将如何?
UPD。 该模型中有几个实体具有Email属性。 所以可能签名会看起来像:
public FancyObject(Entity holder, Expression<Func<T>> selector)
和构造函数调用
var foo = new FancyObject(customer, ()=>customer.Email);
该参数将是一个Expression<Func<Customer,string>> selector
。 读它可以通过平面编译:
Func<Customer,string> func = selector.Compile();
那么你可以访问func(customer)
。 指派更棘手。 对于简单的select器,你可以希望你可以简单地分解为:
var prop = (PropertyInfo)((MemberExpression)selector.Body).Member; prop.SetValue(customer, newValue, null);
但是更复杂的expression式可能需要手动树遍历,或者一些4.0expression式节点types:
Expression<Func<Customer, string>> email = cust => cust.Email; var newValue = Expression.Parameter(email.Body.Type); var assign = Expression.Lambda<Action<Customer, string>>( Expression.Assign(email.Body, newValue), email.Parameters[0], newValue); var getter = email.Compile(); var setter = assign.Compile();
它看起来像这个types必须具有两个types参数 – 源代码和结果。 例如,您可以使用:
var foo = new FancyObject<Customer, string>(customer, c => c.Email);
第一个参数是TSource
types,第二个参数是Expression<Func<TSource, TResult>>
:
public class FancyObject<TSource, TResult> { private readonly TSource value; private readonly Expression<Func<TSource, TResult>> projection; public FancyObject(TSource value, Expression<Func<TSource, TResult>> projection) { this.value = value; this.projection = projection; } }
您可以使这个更简单的使用非genericstypes的静态方法:
var foo = FancyObject.Create(customer, c => c.Email);
这可以使用types推断来计算types参数。