使用属性... INotifyPropertyChanged

jma*_*yor 6 .net c# wpf wcf

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

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

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;
         ...
}
Run Code Online (Sandbox Code Playgroud)

而不是宣布财产

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

        set
        {
                       if (value != this.companyNameValue)
                       {
                          this.companyNameValue = value;
                          NotifyPropertyChanged("CompanyName");
                       }
        }
    }
Run Code Online (Sandbox Code Playgroud)

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

[NotifyPropertyChanged]
public string CompanyName
{
  get;set;
}
Run Code Online (Sandbox Code Playgroud)

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

Pet*_*hie 9

如果有人在这个线程中发生并使用C#5(VS 2012 +,.NET 4.5+).这种情况现在"更容易"完成CallerMemberNameAttribute.此属性应用于字符串参数,并使得编译器在使用默认值(即未传递和参数时)时传入调用方法/属性的名称.使实施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));
    }
}
Run Code Online (Sandbox Code Playgroud)

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

  • 还是没有简单属性那么优雅。这是应该的。 (2认同)

Rog*_*mbe 8

您可以使用PostSharp 执行此操作,但我认为它不会很快出现在核心编译器中.

  • 两个链接都被破坏,答案中没有内容 (2认同)

Age*_*191 6

这种思维方式称为面向方面编程(或面向AOP).您可以通过使用Mono的Cecil添加post构建操作来完成最终结果,以使用该属性浏览属性并修改属性的行为并使用适当的行为吐出新编译的程序集.你可以看看Jason BockDimecast " 利用Cecil将代码注入你的程序集 "