[转]使用CallerMemberName简化InotifyPropertyChanged的实现
原文:https://www.cnblogs.com/TianFang/p/3381484.html
在WPF中,当我们要使用MVVM的方式绑定一个普通对象的属性时,界面上往往需要获取到属性变更的通知,
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));
}
}
}
这么做有一个比较大的隐患,那就是用了字符串的硬编码的方式传递了属性名称,一旦拼写错误或因为重构代码忘记去更新这个字符串时,这样就会导致界面上得不到更新。(本身硬编码的方式来保证两者的一致性就是不靠谱的行为)
虽然这本身并不是问题,但却不是很好的实践。也有人通过一些手段来解决这个问题,有的是通过表达式树,还有的通过Attribute注入的方式。
从性能上来讲,注入是一个比较好的方式,但往往引入了比较复杂的框架。实际上,在C# 5.0中就引入了一个调用方信息的语法方便我们获取调用方的函数名称和位置,通过它可以非常简单快捷的解决上面的这个问题:
class NotifyObject : INotifyPropertyChanged
{
private int number;
public int Number
{
get { return number; }
set { number = value; OnPropertyChanged(); }
} private string text;
public string Text
{
get { return text; }
set { text = value; OnPropertyChanged(); }
} public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName]string propertyName = "")
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
代码很简单,这里就不多介绍了。
更进一步
有的时候,为了减少通知的频率,往往会把通知写出如下形式:
private int number;
public int Number
{
get { return number; }
set
{
if (number == value)
return; number = value;
OnPropertyChanged();
}
} private string text;
public string Text
{
get { return text; }
set
{
if (text == value)
return; text = value;
OnPropertyChanged();
}
}
这种写法非常单调,并且在属性多的时候代码就显得很累赘了。这里我就写了一个通用点的函数把他们统一起来,下次就可以直接用了。
private int number;
public int Number
{
get { return number; }
set { UpdateProper(ref number, value); }
} private string text;
public string Text
{
get { return text; }
set { UpdateProper(ref text, value); }
} protected void UpdateProper<T>(ref T properValue, T newValue, [CallerMemberName] string properName = "")
{
if (object.Equals(properValue, newValue))
return; properValue = newValue;
OnPropertyChanged(properName);
}
由于C#的语法限制,不能在类外部调用event,因此不能写成扩展方法,这里就简单的写成一个对象,下次就直接照着改好了:
class NotifyObject : INotifyPropertyChanged
{
private int number;
public int Number
{
get { return number; }
set { UpdateProper(ref number, value); }
} private string text;
public string Text
{
get { return text; }
set { UpdateProper(ref text, value); }
} protected void UpdateProper<T>(ref T properValue, T newValue, [CallerMemberName] string properName = "")
{
if (object.Equals(properValue, newValue))
return; properValue = newValue;
OnPropertyChanged(properName);
} public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName]string propertyName = "")
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
[转]使用CallerMemberName简化InotifyPropertyChanged的实现的更多相关文章
- 使用CallerMemberName简化InotifyPropertyChanged的实现
在WPF中,当我们要使用MVVM的方式绑定一个普通对象的属性时,界面上往往需要获取到属性变更的通知, class NotifyObject : INotifyPropertyChanged ...
- C# 特性学习之一、CallerMemberName、CallerFilePath和CallerLineNumber
在开发中经常会写个公有静态类记录日志,如下: /// <summary> /// Writes the error. /// </summary> /// <param ...
- 如何优雅的实现INotifyPropertyChanged接口
INotifyPropertyChanged接口在WPF或WinFrom程序中使用还是经常用到,常用于通知界面属性变更.标准写法如下: class NotifyObject : INotifyProp ...
- 转载:如何优雅的实现INotifyPropertyChanged接口
转载来源:http://www.cnblogs.com/TianFang/p/6240933.html 如何优雅的实现INotifyPropertyChanged接口 INotifyPropertyC ...
- C# 5.0中使用CallerMemberName、CallerFilePath和CallerLineNumber获取代码的调用方信息(转载)
很多时候,我们需要在运行过程中记录一些调测的日志信息,如下所示: public void DoProcessing() { TraceMessage("DoProcessing()被XXX调 ...
- C# 各版本新特性
C# 2.0 泛型(Generics) 泛型是CLR 2.0中引入的最重要的新特性,使得可以在类.方法中对使用的类型进行参数化. 例如,这里定义了一个泛型类: class MyCollection&l ...
- C# 5.0中新增特性
C# 5.0随着VisualStudio 2012一起正式发布了,让我们来看看C#5.0中增加了哪些功能. 1. 异步编程 在.Net 4.5中,通过async和await两个关键字,引入了一种新的基 ...
- C# 语言历史版本特性(C# 1.0到C# 7.1汇总更新) C#各版本新特性 C#版本和.NET版本以及VS版本的对应关系
C# 语言历史版本特性(C# 1.0到C# 7.1汇总更新) 2017年08月06日 11:53:13 阅读数:6705 历史版本 C#作为微软2000年以后.NET平台开发的当家语言,发展至今具有1 ...
- C# 5.0新加特性
1. 异步编程 在.Net 4.5中,通过async和await两个关键字,引入了一种新的基于任务的异步编程模型(TAP).在这种方式下,可以通过类似同步方式编写异步代码,极大简化了异步编程模型.如下 ...
随机推荐
- LeetCode 题解之Plus One
1.题目描述 2.题目分析 从后向前做加法,等于10则进位,否则直接加1 ,返回 digits; 3.代码 vector<int> plusOne(vector<int>&am ...
- 5.String StringBuffer StringBuilder
String,StringBuffer和StringBuilder三者的讲解 对于StringBuffer和StringBuilder是对Stirng的一个优化. 之前已经说过了,String对象一旦 ...
- Linux 用户和用户组详解
用户分类 超级用户:UID范围 0 root用户:uid=0(root) gid=0(root) groups=0(root) 普通用户:由管理员创建,UID范围(500-65535) --> ...
- Linux 系统的/etc目录
/etc目录下的重要文件 /etc/sysconfig/network 指定服务器上的网络配置信息 /etc/rc.d/init.d/network 网络配置脚本信息 网络配置脚本,开机通过脚本文件来 ...
- November 30th 2016 Week 49th Wednesday
Your attitude, not your aptitude, will determine your altitude. 决定你人生高度的,不是你的才能,而是你的态度. Basically, I ...
- 列表 ->join---> 字符串 转类型:x--->y类型 y(x)
列表 ->join---> 字符串 转类型:x--->y类型 y(x)
- 原生JS 将canvas生成图片
核心代码: <script type="text/javascript"> // Converts image to canvas; returns new canva ...
- PHP设计模式系列 - 委托模式
委托模式 通过分配或委托其他对象,委托设计模式能够去除核心对象中的判决和复杂的功能性. 应用场景 设计了一个cd类,类中有mp3播放模式,和mp4播放模式 改进前,使用cd类的播放模式,需要在实例化的 ...
- Promise & Deferred Objects in JavaScript Pt.2: in Practice
原文:http://blog.mediumequalsmessage.com/promise-deferred-objects-in-javascript-pt2-practical-use Intr ...
- Result工具类
使用ajax请求访问时,可以用此工具类作为返回对象,也方便统一代码规范 package com.ujia.entity; import java.io.Serializable; public cla ...