如何使用Expression Tree来设置和获取对象属性?
,而不是使用Reflection我写了下面的课程,工作正常:
public class PropertyAccessor<TEntity>
{
private readonly PropertyInfo _memberInfo;
private readonly TEntity _nom;
public PropertyAccessor(Expression<Func<TEntity, object>> fieldSelector, TEntity nom)
{
if (fieldSelector.Body is MemberExpression)
_memberInfo = (PropertyInfo)((MemberExpression)fieldSelector.Body).Member;
else if (fieldSelector.Body is UnaryExpression)
_memberInfo = (PropertyInfo)((MemberExpression)((UnaryExpression)fieldSelector.Body).Operand).Member;
else
throw new NotImplementedException("Field selector not supported");
_nom = nom;
}
public object Value
{
get { return _memberInfo.GetValue(_nom, null); }
set { _memberInfo.SetValue(_nom, value, null); }
}
}
我这样用它:
Product product = ProductFactory.Build();
var propertyAccessor = new PropertyAccessor<Product>(p => p.Name, product);
var name = propertyAccessor.Value;
有没有办法进一步提高其性能?实施是最好的方法吗?
我不应该在构造函数调用之前或之后对表达式调用Compile()方法吗?
将lambda表达式传递给该lambda表达式的表达式会发生什么?
将MemberExpression转换为PropertyInfo是最佳选择吗?任何表现处罚?
答案 0 :(得分:0)
请记住,属性实际上是两个独立的方法,一个get和一个set。我也没有看到任何理由在这里使用表达式,所以我使用了代理。如果必须使用表达式,则可以先编译它。
public class PropertyAccessor<TEntity,TProperty>
{
private readonly TEntity _nom;
Func<TEntity, TProperty> _getter;
Action<TEntity, TProperty> _setter;
public PropertyAccessor(Func<TEntity, TProperty> getter, Action<TEntity, TProperty> setter, TEntity nom)
{
_getter = getter;
_setter = setter;
_nom = nom;
}
public object Value // the return type can be changed to TProperty
{
get { return _getter(_nom); }
set { _setter(_nom, (TProperty)value); }
}
}
可以这样调用:
var propertyAccessor = new PropertyAccessor<Product, String>(p => p.Name, (p, v) => p.Name = v, product);