簡體   English   中英

在C#中按名稱獲取和保留屬性引用的最佳方法是什么

[英]What is the best way get and hold property reference by name in c#

我想知道是否有更好的方法(比我目前正在做的更好)來獲取和持有僅使用對象和屬性字符串名稱的另一個對象中對屬性的引用。 尤其是,是否有更好的方法利用.Net 4.0的新動態功能來做到這一點?

這就是我現在所擁有的。

我有一個“ PropertyReference<T> ”對象,該對象在構造函數中帶有對象名稱和屬性名稱。

Initialize()方法使用反射來查找對象和屬性,並將Getter屬性存儲為Action<T>而將Setter屬性存儲為Func<T>

當我想實際調用該屬性時,請執行以下操作:

int x = _propertyReference.Get();

要么

_propertyReference.Set(2);

這是我的PropertyReference<T>代碼。 請剖析並提出改進建議。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Xml;

namespace WindowsFormsApplication2
{
    public class PropertyReference<T> : IPropertyReference
    {
        public string ComponentName { get; set; }
        public string PropertyName { get; set; }
        public bool IsInitialized
        {
            get
            {
                return (_action != null && _func != null);
            }
        }

        Action<T> _action;
        Func<T> _func;

        public PropertyReference() { }

        public PropertyReference(string componentName, string propertyName)
        {
            ComponentName = componentName;
            PropertyName = propertyName;
        }

        public void Initialize(IEntity e)
        {            
            Object component = e.GetByName(ComponentName);
            if (component == null) return;

            Type t = e.GetByName(ComponentName).GetType();
            PropertyInfo pi = t.GetProperty(PropertyName);

            _action = (T a) => pi.SetValue(component, a, null);
            _func = () => (T)pi.GetValue(component, null);
        }

        public void Reset()
        {
            _action = null;
            _func = null;

        }

        public void Set(T value)
        {
            _action.Invoke(value);
        }

        public T Get()
        {
            return _func();
        }

    }
}

注意:我不能使用“發射”功能,因為我需要此代碼在新的Windows Phone 7上工作,並且不支持發射。

更新:

更換后只是做了一些速度測試:

_action = (T a) => pi.SetValue(component, a, null);
_func = () => (T)pi.GetValue(component, null);

_action = Action<T>)Delegate.CreateDelegate(typeof(Action<T>),component,pi.GetSetMethod());
_func = (Func<T>)Delegate.CreateDelegate(typeof(Func<T>), component, pi.GetGetMethod());

如以下dtb所建議。

通過對Get()屬性進行100,000次調用進行了測試。 這是結果。

_func = () => (T)pi.GetValue(component, null)

花了大約200ms

_func = (Func<T>)Delegate.CreateDelegate(typeof(Func<T>), component, pi.GetGetMethod());

花了大約10ms

差異很大。 沒想到,但是很酷!

仍然需要更多改進。

您可以獲得直接代表getter和setter方法的委托:

object component;
PropertyInfo pi;

_action = (Action<T>)Delegate.CreateDelegate(typeof(Action<T>),
                                             component,
                                             pi.GetSetMethod());

_func = (Func<T>)Delegate.CreateDelegate(typeof(Func<T>),
                                         component,
                                         pi.GetGetMethod());

這實際上取決於您要多久調用一次。 如果不是很大的吞吐量,那很好-但是請注意,基於反射的GetValue / SetValue相當慢。 您可以緩存委托,但是另一種簡單的方法可能是查看HyperDescriptor-它使用與PropertyDescriptor相同的API(因此您再次獲得GetValue / SetValue ),但是它在下面使用了動態方法。 然后,API類似於:

PropertyDescriptor prop = TypeDescriptor.GetProperties(type)["PropertyName"];

要么

PropertyDescriptor prop = TypeDescriptor.GetProperties(obj)["PropertyName"];

然后

object value = prop.GetValue(component);
prop.SetValue(component, newValue);

暫無
暫無

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

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