我已经看到了各种方法,包括反射,组件模型类型描述符,表达式树和方面,但我仍然不确定下面的代码是否使用.Net 4.0或更高版本实现了以下所有目标:< / p>
如何改进代码?
protected void NotifyOfPropertyChanging<TProperty>(Expression<Func<TProperty>> property) {
var memberExpression = (MemberExpression)property.Body;
var prop = (PropertyInfo) memberExpression.Member;
var propertyName = prop.Name;
var value = prop.GetValue(this, null);
// fire INPC using propertyName
// use value and name to do IsDirty checking
}
答案 0 :(得分:1)
您可能能够通过编译表达式树并将其缓存以备将来使用来提高性能,而不是每次都调用GetValue
。但是,只有当您的当前实现导致瓶颈时,才应进行此类优化。
void NotifyOfPropertyChanging<TProperty>(Expression<Func<TProperty>> property)
{
var memberExpression = (MemberExpression) property.Body;
var prop = (PropertyInfo) memberExpression.Member;
Func<TProperty> accessor;
if (!TypedAccessorCache<TProperty>.Cache.TryGetValue(prop, out accessor))
{
accessor = property.Compile();
TypedAccessorCache<TProperty>.Cache[prop] = accessor;
}
var value = accessor();
// ...
}
static class TypedAccessorCache<TProperty>
{
public static readonly IDictionary<PropertyInfo, Func<TProperty>> Cache =
new Dictionary<PropertyInfo, Func<TProperty>>();
}
注意我使用了通用的静态类型来保存缓存字典实例。这是为每种不同属性类型有效创建单独类型缓存的便捷方法。
答案 1 :(得分:0)
这是一个很长的故事,我想仍然没有一种方法比其他方法更好。我认为这些表达式在大多数通常的业务场景中都不会成为一个性能瓶颈(如果你需要的话,你可以优化一小段需要更快通知的代码),所以这种方法应该没问题。
请记住,创建表达式树比解析它要花费更多时间,因此请确保只执行一次(即使用静态类级表达式变量)。但是,在这种情况下,您的模型代码会变得有点臃肿。
我个人更喜欢使用基于字符串的INPC处理。在重构时,ReSharper可以很好地处理字符串,所以我可以称之为相对安全。据我所知,这是最快的方法。使用VS或ReSharper片段,您可以轻松地在几次击键中编写属性。
关于属性值 - INotifyPropertyChanging 既不使用也不使用 INotifyPropertyChanged 接口。你为什么需要它?