C#优雅的实现INotifyPropertyChanged接口
INotifyPropertyChanged接口在WPF或WinFrom程序中使用还是经常用到,常用于通知界面属性变更。标准写法如下:
class NotifyObject : INotifyPropertyChanged{private int number; public int Number{get { return number; }set { number = value; OnPropertyChanged("Number"); }}private string text; public string Text{get { return text; }set { text = value; OnPropertyChanged("Text"); }}public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string propertyName = ""){PropertyChangedEventHandler handler = PropertyChanged; if (handler != null){handler(this, new PropertyChangedEventArgs(propertyName)); }}}
这种写法的两个问题是
- 对属性名使用了字符串硬编码,容易写错,也不方便重构
- 冗余代码,如果属性较多的时候写得想吐
- 通过代理对象封装
- 通过编译期间代码注入的方式实现
这种方式是动态的AOP了,是一个通用的方式,并且扩展性比较器,可以通过继承PocoNotifyWrapper来实现多态。用它做ViewMode层还是比较方便。
不过一个不大好的地方是DynamicObject是丢失了属性类型信息的,有时绑定时会出错(如将一个TextBox的Text绑定到一个封装后的Int类型对象时会不进行自动类型转换)。要解决它还需要实现一些其它的接口,实现起来还是有些复杂的,并且项目进度比较紧张,没有太多时间来完善它。
另外一种方式是通过编译期间代码注入方式来实现:
文章图片
文章图片
最开始见的是PostSharp的一个实现: http://doc.postsharp.net/inotifypropertychanged-add。不过PostSharp是收费的,后来也逐渐由了许多其它的免费的解决方案。本文这里介绍的是一个开源的解决方案:Fody。
使用它非常简单,首先通过Nuget安装库:
PM> Install-Package PropertyChanged.Fody
。然后在需要实现属性通知的类上加一个[ImplementPropertyChanged]即可:[ImplementPropertyChanged]public class Person{public string GivenNames { get; set; }public string FamilyName { get; set; }public string FullName => string.Format("{0} {1}", GivenNames, FamilyName); }
编译后生成的代码如下:
public class Person : INotifyPropertyChanged{public event PropertyChangedEventHandler PropertyChanged; string givenNames; public string GivenNames{get { return givenNames; }set{if (value != givenNames){givenNames = value; OnPropertyChanged("GivenNames"); OnPropertyChanged("FullName"); }}}string familyName; public string FamilyName{get { return familyName; }set {if (value != familyName){familyName = value; OnPropertyChanged("FamilyName"); OnPropertyChanged("FullName"); }}}public string FullName{get{return string.Format("{0} {1}", GivenNames, FamilyName); }}public virtual void OnPropertyChanged(string propertyName){var propertyChanged = PropertyChanged; if (propertyChanged != null){propertyChanged(this, new PropertyChangedEventArgs(propertyName)); }}}
基本上对代码没有注入,不需要安装插件,也不影响调试,实现非常简单,非常方便。
需要注意的是,如果实现了INotifyPropertyChanged接口,即使没有[ImplementPropertyChanged]标记,默认也会注入。
【C#优雅的实现INotifyPropertyChanged接口】以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对脚本之家的支持。如果你想了解更多相关内容请查看下面相关链接
推荐阅读
- 你的周围是否也有这样在自黑的路上越走越远的朋友
- (二)虽万千人吾往矣——记录全职妈妈努力码字的日子
- 最动人的风景是人
- 人生是场修行
- 第八日的蝉
- 30岁,背上行囊 ,走自己的路
- python|利用deepstream python将analytics产生的统计数据发送到kafka
- python|Python3中的算术运算符
- 脆弱的心灵
- 产品工作中的一些小小体验之——|产品工作中的一些小小体验之—— 怎样更好地了解你的用户