如何实现 INotifyPropertyChanged 使用名称而不是魔术字符串
本文关键字:字符串 魔术 何实现 实现 INotifyPropertyChanged | 更新日期: 2023-09-27 18:34:11
我正在阅读有关 C# 6 中新的 nameof
关键字的信息。我想知道如何使用此关键字实现INotifyPropertyChanged
,先决条件是什么(当然除了 C# 6 之外)以及它将如何影响我的 MVVM 应用程序的性能?
它看起来像这样:
public string Foo
{
get
{
return this.foo;
}
set
{
if (value != this.foo)
{
this.foo = value;
OnPropertyChanged(nameof(Foo));
}
}
}
nameof(Foo)
将在编译时替换为"Foo"字符串,因此它应该非常高效。这不是反思。
这只是使用nameof()
而不是魔术字符串的问题。下面的示例来自我关于该主题的博客文章:
private string currentTime;
public string CurrentTime
{
get
{
return this.currentTime;
}
set
{
this.currentTime = value;
this.OnPropertyChanged(nameof(CurrentTime));
}
}
由于它是在编译时计算的,因此它比任何当前的替代方案(博客文章中也提到)都更具性能。
下面是
使用新的 C# 6.0 糖的类的完整代码示例:
public class ServerViewModel : INotifyPropertyChanged {
private string _server;
public string Server {
get { return _server; }
set {
_server = value;
OnPropertyChanged(nameof(Server));
}
}
private int _port;
public int Port {
get { return _port; }
set {
_port = value;
OnPropertyChanged(nameof(Port));
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
这样,您可以获得nameof()
运算符、空条件运算符?.
和一个表达式体函数(OnPropertyChanged
定义)。
我发现使用PropertyChanged.Fody要容易得多,因为您最终会得到更少的错误和更干净的代码,请参阅-https://github.com/Fody/PropertyChanged
您所要做的就是用ImplementPropertyChanged
属性标记您的类:
[ImplementPropertyChanged]
public class Person
{
public string GivenNames { get; set; }
public string FamilyName { get; set; }
public string FullName
{
get
{
return 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.PropertyChanged Event 的文档
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}