如何以最佳方式使用表达式树获取和设置属性

本文关键字:获取 设置 属性 表达式 最佳 方式使 | 更新日期: 2023-09-27 18:33:26

如何使用表达式树设置和获取对象属性,而不是使用反射?

我写了下面的类,工作正常:

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 是最佳选择吗? 任何绩效处罚?

如何以最佳方式使用表达式树获取和设置属性

请记住,属性实际上是两个独立的方法,一个 get 和一个集合。我也没有看到任何理由在这里使用表达式,所以我使用了委托。如果必须使用表达式,可以先编译它。

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);