【问题标题】:Use of Attributes... INotifyPropertyChanged使用属性... 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;
}

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

【问题讨论】:

    标签: c# .net wpf wcf


    【解决方案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 BockDimecast

    【讨论】:

    • 非常好阅读.. 非常感谢... 我开始使用 postsharp... 这就是为什么我要指出另一个答案。但这也很有用。
    猜你喜欢
    • 1970-01-01
    • 2017-05-22
    • 1970-01-01
    • 2010-12-07
    • 2013-01-14
    • 2011-03-21
    • 2013-08-12
    • 2011-01-15
    • 2019-04-04
    相关资源
    最近更新 更多