c# - 使用 nameof 运算符而不是 CallerMemberNameAttribute 来通知 .NET 4.5.3 中的属性更改有什么好处吗?

标签 c# c#-6.0 .net-4.6 callermembername nameof

随着 .NET 4.5.3 的出现,WPF 开发人员现在可以通过三种(或更多)方式通知 INotifyPropertyChanged Interface的属性变化。基本上,我的问题是从 .NET 4.5 开始引入的两种方法中,哪种方法更有效地通知属性更改,以及在 WPF 中使用这两种方法是否有任何好处?

背景

对于那些不太熟悉这个主题的人,这里是主要的三种方法。第一种是原始的、更容易出错的简单传递字符串的方法:

public string TestValue
{
    get { return testValue; }
    set { testValue = value; NotifyPropertyChanged("TestValue"); }
}

protected virtual void NotifyPropertyChanged(string propertyName)
{
    if (PropertyChanged != null)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

第二种方法是.NET 4.5引入的; CallerMemberNameAttribute :

public string TestValue
{
    get { return testValue; }
    set { testValue = value; NotifyPropertyChanged(); }
}

protected virtual void NotifyPropertyChanged([CallerMemberName]string propertyName = "")
{
    if (PropertyChanged != null)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

第三种也是最新的方法是(或即将)作为 .NET 4.5.3 的一部分在 C#6.0 中引入的; nameof Operator :

public string TestValue
{
    get { return testValue; }
    set { testValue = value; NotifyPropertyChanged(nameof(TestValue)); }
}

protected virtual void NotifyPropertyChanged(string propertyName)
{
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

我自己的假设是,最初的、更容易出错的简单传递字符串的方法是最有效的,因为我只能想象其他两种方法使用某种形式的反射。但是,我真的很想知道其他两种方法中哪一种更有效,以及使用 CallerMemberNameAttribute 属性和 nameof 运算符之间是否真的有任何区别在 WPF 上下文中。

最佳答案

关于效率:直接使用字符串,CallerMemberNameAttributenameof都是完全一样的,因为字符串是编译器在编译时注入(inject)的。不涉及反射。

我们可以看到使用 TryRoslyn produces this for CallerMemberNameAttribute :

public string TestValue
{
    get { return this.testValue; }
    set { this.testValue = value; this.NotifyPropertyChanged("TestValue"); }
}
protected virtual void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
    if (this.PropertyChanged != null)
    {
        this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

this for nameof :

public string TestValue
{
    get { return this.testValue; }
    set { this.testValue = value; this.NotifyPropertyChanged("TestValue"); }
}
protected virtual void NotifyPropertyChanged(string propertyName)
{
    if (this.PropertyChanged != null)
    {
        this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

由于在运行时所有选项都只是一个字符串,因此 WPF 上下文没有问题。

关于方便:CallerMemberNameAttribute 要求您有一个可选参数,而 nameof 不需要,但是 nameof 要求您指定属性,而 CallerMemberNameAttribute 没有。

我预测 nameof 会变得如此流行以致于使用它会简单得多。

关于c# - 使用 nameof 运算符而不是 CallerMemberNameAttribute 来通知 .NET 4.5.3 中的属性更改有什么好处吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28397256/

相关文章:

c# - 与 C# 的所有事物保持同步

c# - 为什么 python 请求工作但 C# 请求不工作?

android - 使用适用于 Visual Studio 2015 预览版的 Xamarin 扩展创建 Android 应用程序时出现构建错误

c# - EF4 代码优先 : how to add a relationship without adding a navigation property

c# - 侧滚动瓦片 map , map 变得困惑

c# - Readonly getters VS 类似属性的函数

c# - 插入字符串 c# 6.0 和 Stylecop

c# - 如何为 VisualStudio2015 设置 .NET 版本(代码)

c# - ViewModel 自动具有与通用模型相同的属性

generics - 相互定义的参数中的 F# 通用单位