2015-02-08 4 views
18

С появлением .NET 4.5.3 разработчики WPF теперь имеют три (или более) способа уведомления об изменениях свойств INotifyPropertyChanged Interface. В основном, мой вопрос: . Какой из двух методов, введенных с .NET 4.5, является более эффективным способом уведомления об изменениях свойств и имеет ли какой-либо эффект при использовании в WPF?Есть ли какая-либо польза от использования оператора nameof вместо CallerMemberNameAttribute для уведомления изменений свойств в .NET 4.5.3?

фон

Для тех, кто не так хорошо знакомы с этой темой, вот основные три метода. Первым из них является оригинальным, более подвержен ошибкам метод просто передавая строку:

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)); 
    } 
} 

Третий и последний метод был (или скоро будет), введенный в С # 6.0 как часть .NET 4.5.3; 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.

+0

«Третий и последний метод (или скоро будет) введен в C# 6.0, как часть .NET 4.5.3, имя оператора »- строго говоря,« имя »- это [функция языка] (https://github.com/dotnet/roslyn/wiki/New-Language-Features-in-C%23 -6), а не часть структуры. –

ответ

24

Об эффективности: используя строку непосредственно, CallerMemberNameAttribute, nameof все точно такие же, поскольку строка впрыскивается компилятором во время компиляции. В этом нет никакого отражения.

Мы можем видеть, что с помощью 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)); 
    } 
} 

Поскольку во время выполнения всех вариантов просто в string нет никаких проблем с контекстом WPF.

О удобства: CallerMemberNameAttribute необходимо иметь дополнительный параметр, в то время как nameof не но nameof требует, чтобы указать свойство, а CallerMemberNameAttribute нет.

Я предсказываю, что nameof окажется настолько популярным, что вместо него было бы намного проще использовать его.

+1

Почему имя будет настолько популярным? Гораздо проще использовать CallerMemberNameAttribute, как один раз, или, как правило, по меньшей мере меньше имени (которое вы должны использовать в каждом свойстве). Я не понимаю эти тенденции ... Можете ли вы объяснить, пожалуйста? –

+0

@ElMac nameof уже оказалось популярным во многих сценариях ... не только для получения имени вызывающего абонента. Больше людей знают это и используют его повсюду, поэтому его проще использовать здесь. – i3arnon

6

CallerMemberNameAttribute может использоваться только для вызываемой функции, чтобы получить имя функции вызывающего абонента.

Оператор nameof выходит за пределы этого. Его можно использовать везде.

Если вы хотите, чтобы рассуждать о ней только в рамках данных WPF связывания, возьмите этот пример:

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)); 
     } 
    } 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^