使用属性... INotifyPropertyChanged

Posted

技术标签:

【中文标题】使用属性... INotifyPropertyChanged【英文标题】:Use of Attributes... INotifyPropertyChanged 【发布时间】:2010-12-12 09:00:07 【问题描述】:

这只是我在学习 Attributes 时的想法,而且我使用 INotifyPropertyChanged 太多了,只是和 Idea,我想听听一些关于它的意见。(我知道这需要在编译器而不是消费者端)

由于 INotifyPropertyChanged 大部分时间都与相同的 Pattern 一起使用.. 就像使用属性名称调用触发事件的方法一样,它可以设计为 Attribute 并使用 Auto-Properties 吗?以便编译器知道它需要添加对 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;
         ...

而不是声明属性

public string CompanyName
    
        get
        
            return this.companyNameValue;
        

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

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

[NotifyPropertyChanged]
public string CompanyName

  get;set;

在不使用属性的情况下,我们仍然可以为某些自定义行为保持旧的编码方式..

【问题讨论】:

【参考方案1】:

万一有人遇到这个线程并且使用 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));
    

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

【讨论】:

仍然没有简单属性那么优雅。它应该是什么。 这是一次完成,甚至可以作为其他类的基类。为每个属性添加一个属性是否更优雅? 当然,只是不能使用默认的道具定义。 好的,是的。如果它是基本关闭,您可以使用默认属性。但我认为默认值在很大程度上是特定于实现的。您仍然可以将默认属性放在实现类中的属性上。属性更改处理程序不需要更改以支持...【参考方案2】:

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

【讨论】:

非常好阅读.. 非常感谢... 我开始使用 postsharp... 这就是为什么我要指出另一个答案。但这也很有用。

以上是关于使用属性... INotifyPropertyChanged的主要内容,如果未能解决你的问题,请参考以下文章

如何使用属性选择器

z-index怎么使用,啥时候使用这个属性

ANT 从属性文件中读取属性,使用 ANT 属性

使用 mvn 版本排除属性:使用 excludesList 更新属性

156 对象的理解和使用,什么时候必须 使用['属性名'] 的方式

在另一个模块使用此属性之前,如何使用指令添加属性?