首页 文章

使用属性... INotifyPropertyChanged

提问于
浏览
6

这是我正在思考的事情,因为我正在学习属性,而我正在使用INotifyPropertyChanged太多,只是和想法,我想听听它的一些意见 . (我知道这需要在编译器上做一些工作而不是在cosumer方面)

由于INotifyPropertyChanged大部分时间都使用相同的模式 . 就像调用使用属性名称激活事件的方法一样,它可以设计为和属性并使用自动属性吗?这样编译器知道它需要添加对PropertyChanged事件的调用吗?所以,如果我们有 class ....

public class DemoCustomer : INotifyPropertyChanged
{
  public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged(String info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }

  private string companyNameValue = String.Empty;
         ...
}

而不是宣布 property

public string CompanyName
    {
        get
        {
            return this.companyNameValue;
        }

        set
        {
                       if (value != this.companyNameValue)
                       {
                          this.companyNameValue = value;
                          NotifyPropertyChanged("CompanyName");
                       }
        }
    }

如果我们可以通过此属性向编译器指示如果新值与前一个值不同,则需要使用属性的名称生成对PropertyChanged的调用,我们可以执行类似这样的操作

[NotifyPropertyChanged]
public string CompanyName
{
  get;set;
}

当没有使用属性时,我们仍然可以使用旧方式对某些自定义行为进行编码 .

3 回答

  • 8

    你可以do thisPostSharp,但我不会很快在核心编译器中 .

  • 4

    如果有人发生在这个线程中并使用C#5(VS 2012,.NET 4.5) . 这个案例现在用 CallerMemberNameAttribute 完成"more easily" . 此属性应用于字符串参数,并使得编译器在使用默认值(即未传递和参数时)时传入调用方法/属性的名称 . 实施 INotifyPropertyChanged 不那么烦人 . 例如:

    public class MyClass
    {
        private string myProperty;
    
        public string MyProperty
        {
            get { return myProperty; }
            set
            {
                myProperty = value;
                OnPropertyChanged();
            }
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            var handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    

    因此,您只需要在每个setter中发送 OnPropertyChanged() 来发送事件,而不必处理属性名称的硬编码字符串 .

  • 8

    这种思维方式称为面向方面编程(或面向AOP) . 您可以通过使用Mono的Cecil添加post构建操作来完成最终结果,以使用该属性浏览属性并修改属性的行为并使用适当的行为吐出新编译的程序集 . 你可以在“Leveraging Cecil to inject code into your Assemblies”上查看Jason BockDimecast

相关问题