INotifyPropertyChanged 属性名称 - 硬编码与反射? [英] INotifyPropertyChanged property name - hardcode vs reflection?

查看:19
本文介绍了INotifyPropertyChanged 属性名称 - 硬编码与反射?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 INotifyPropertyChanged 时指定属性名称的最佳方法是什么?

What is the best way to specify a property name when using INotifyPropertyChanged?

大多数示例将属性名称硬编码为 PropertyChanged 事件的参数.我正在考虑使用 MethodBase.GetCurrentMethod.Name.Substring(4) 但对反射开销有点不安.

Most examples hardcode the property name as an argument on the PropertyChanged Event. I was thinking about using MethodBase.GetCurrentMethod.Name.Substring(4) but am a little uneasy about the reflection overhead.

推荐答案

不要忘记一件事:PropertyChanged 事件主要由将使用反射的组件消耗获取命名属性的值.

Don't forget one thing : PropertyChanged event is mainly consumed by components that will use reflection to get the value of the named property.

最明显的例子是数据绑定.

The most obvious example is databinding.

当您触发 PropertyChanged 事件,将属性名称作为参数传递时,您应该知道此事件的订阅者很可能通过调用使用反射,例如,GetProperty(至少是第一次,如果它使用 PropertyInfo 的缓存),然后是 GetValue.最后一次调用是属性 getter 方法的动态调用 (MethodInfo.Invoke),其成本高于仅查询元数据的 GetProperty.(请注意,数据绑定依赖于整个 TypeDescriptor 事情——但是默认实现使用反射.)

When you fire PropertyChanged event, passing the name of the property as a parameter, you should know that the subscriber of this event is likely to use reflection by calling, for instance, GetProperty (at least the first time if it uses a cache of PropertyInfo), then GetValue. This last call is a dynamic invocation (MethodInfo.Invoke) of the property getter method, which costs more than the GetProperty which only queries meta data. (Note that data binding relies on the whole TypeDescriptor thing -- but the default implementation uses reflection.)

因此,当然,在触发 PropertyChanged 时使用硬编码属性名称比使用反射动态获取属性名称更有效,但恕我直言,平衡您的想法很重要.在某些情况下,性能开销并不那么重要,您可以从某种强类型事件触发机制中受益.

So, of course using hard code property names when firing PropertyChanged is more efficient than using reflection for dynamically getting the name of the property, but IMHO, it is important to balance your thoughts. In some cases, the performance overhead is not that critical, and you could benefit from some kind on strongly typed event firing mechanism.

以下是我在 C# 3.0 中有时使用的,当性能不是问题时:

Here is what I use sometimes in C# 3.0, when performances would not be a concern :

public class Person : INotifyPropertyChanged
{
    private string name;

    public string Name
    {
        get { return this.name; }
        set 
        { 
            this.name = value;
            FirePropertyChanged(p => p.Name);
        }
    }

    private void FirePropertyChanged<TValue>(Expression<Func<Person, TValue>> propertySelector)
    {
        if (PropertyChanged == null)
            return;

        var memberExpression = propertySelector.Body as MemberExpression;
        if (memberExpression == null)
            return;

        PropertyChanged(this, new PropertyChangedEventArgs(memberExpression.Member.Name));
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

注意使用表达式树来获取属性的名称,以及使用 lambda 表达式作为 Expression :

Notice the use of the expression tree to get the name of the property, and the use of the lambda expression as an Expression :

FirePropertyChanged(p => p.Name);

这篇关于INotifyPropertyChanged 属性名称 - 硬编码与反射?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆