首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在.NET 4.5.3中,使用nameof操作符而不是CallerMemberNameAttribute来通知属性更改有什么好处吗?

在.NET 4.5.3中,使用nameof操作符而不是CallerMemberNameAttribute来通知属性更改有什么好处吗?
EN

Stack Overflow用户
提问于 2015-02-09 01:51:23
回答 2查看 6.4K关注 0票数 23

随着WPF4.5.3的到来,.NET开发人员现在有三种(或更多)方法来通知INotifyPropertyChanged Interface属性更改。基本上,我的问题是,从WPF4.5开始引入的两种方法中,哪一种是更有效的通知属性更改的方式,以及在from.NET中使用这两种方式是否有任何好处?

背景

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

代码语言:javascript
复制
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

代码语言:javascript
复制
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

代码语言:javascript
复制
public string TestValue
{
    get { return testValue; }
    set { testValue = value; NotifyPropertyChanged(nameof(TestValue)); }
}

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

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-02-09 02:03:53

关于效率:直接使用字符串,CallerMemberNameAttributenameof都是完全相同的,因为字符串是在编译时由编译器注入的。没有涉及到反射。

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

代码语言:javascript
复制
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

代码语言:javascript
复制
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));
    }
}

因为在运行时所有的选项都是一个简单的string,所以WPF上下文没有问题。

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

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

票数 32
EN

Stack Overflow用户

发布于 2015-02-09 03:31:03

CallerMemberNameAttribute只能用于被调用的函数,以获取调用方函数的名称。

nameof操作符远远超出了这一点。它可以在任何地方使用。

如果您只想在WPF数据绑定的范围内对其进行推理,请使用以下示例:

代码语言:javascript
复制
public string FullName
{
   get
   {
       return string.Format(
           "{0} {1}",
           this.firstName,
           this.lastName);
   }
}

public string FirstName
{
   get
   {
       return this.firstName;
   }
   set
   {
       if (value != this.firstName)
       {
           this.firstName = value;
           NotifyPropertyChanged(nameof(FirstName));
           NotifyPropertyChanged(nameof(FullName));
        }
   }
}

public string LasttName
{
   get
   {
       return this.lastName;
   }
   set
   {
       if (value != this.lastName)
       {
           this.lastName = value;
           NotifyPropertyChanged(nameof(LasttName));
           NotifyPropertyChanged(nameof(FullName));
        }
   }
}
票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28397256

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档