C# 在c中,按名称获取和保存属性引用的最佳方法是什么#

C# 在c中,按名称获取和保存属性引用的最佳方法是什么#,c#,reflection,dynamic,.net-4.0,C#,Reflection,Dynamic,.net 4.0,我想知道是否有更好的方法(比我目前正在做的事情)来获取和保存对另一个对象中的属性的引用,只使用对象和属性字符串名称。特别是,使用.NET4.0的新动态功能是否有更好的方法来实现这一点 这是我现在拥有的 我有一个“PropertyReference”对象,它在构造函数中采用对象名和属性名 Initialize()方法使用反射查找对象和属性,并将属性Getter存储为Action,将属性Setter存储为Func 当我想实际调用属性时,我会这样做: int x = _propertyReferenc

我想知道是否有更好的方法(比我目前正在做的事情)来获取和保存对另一个对象中的属性的引用,只使用对象和属性字符串名称。特别是,使用.NET4.0的新动态功能是否有更好的方法来实现这一点

这是我现在拥有的

我有一个“
PropertyReference
”对象,它在构造函数中采用对象名和属性名

Initialize()
方法使用反射查找对象和属性,并将属性Getter存储为
Action
,将属性Setter存储为
Func

当我想实际调用属性时,我会这样做:

int x = _propertyReference.Get();

这是我的
属性参考
代码。请仔细分析并提出改进建议

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

    }
}

花了大约200毫秒

_func = (Func<T>)Delegate.CreateDelegate(typeof(Func<T>), component, pi.GetGetMethod());
\u func=(func)Delegate.CreateDelegate(typeof(func),component,pi.getMethod());
大约用了10毫秒

差别很大。没想到会这样,但很酷


仍有待进一步改进。

您可以获得直接代表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());
对象组件;
房地产信息;
_action=(action)Delegate.CreateDelegate(typeof(action),
组成部分
pi.GetSetMethod());
_func=(func)Delegate.CreateDelegate(typeof(func),
组成部分
pi.getMethod());

这实际上取决于您调用它的频率。如果吞吐量不是很大,那么也可以,但是请注意,基于反射的
GetValue
/
SetValue
非常慢。您可以缓存代理,但另一个简单的方法可能是查看—它使用与
PropertyDescriptor
相同的API(因此您再次获得
GetValue
/
SetValue
),但它在下面使用动态方法。然后,API类似于:

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

然后


您是否确定Win7智能手机将提供
动态
?这是一个相当复杂的行为,我不被支持。反思没有灵丹妙药,所有建议的解决方案都使用它。包括动态。不,我不确定。。我会调查的。用一些性能结果更新了原始问题。如上所述。Fasterflect()似乎是一个更全面的库,其用途与HyperDescriptor类似,尽管他确实提到了反射。Emit不是一个选项(这将排除这两种建议)。@Morten-我错过了问题中的警告-所以是的,这排除了它们。Bummer,这听起来是一个很好的解决方案。我确实查看了Fasterflect并通过电子邮件发送给开发人员,这就是我发现Emit在Windows Phone 7上不起作用的原因。这看起来比我现有的更简洁。我会试着把这个结合起来。如果有人有其他想法,我们仍在寻找。
_func = () => (T)pi.GetValue(component, null)
_func = (Func<T>)Delegate.CreateDelegate(typeof(Func<T>), component, pi.GetGetMethod());
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());
PropertyDescriptor prop = TypeDescriptor.GetProperties(type)["PropertyName"];
PropertyDescriptor prop = TypeDescriptor.GetProperties(obj)["PropertyName"];
object value = prop.GetValue(component);
prop.SetValue(component, newValue);