C# 在c中,按名称获取和保存属性引用的最佳方法是什么#
我想知道是否有更好的方法(比我目前正在做的事情)来获取和保存对另一个对象中的属性的引用,只使用对象和属性字符串名称。特别是,使用.NET4.0的新动态功能是否有更好的方法来实现这一点 这是我现在拥有的 我有一个“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
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);