簡體   English   中英

如何以最佳方式使用表達式樹獲取和設置屬性?

[英]How to Get and Set a Property using Expression Trees in the Best Way?

而不是使用反射,如何使用表達式樹設置和獲取對象屬性?

我寫了下面的類,可以正常工作:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM