2015-02-08 3 views
18

Mit dem Aufkommen von .NET 4.5.3 haben WPF-Entwickler jetzt drei (oder mehr) Möglichkeiten, die INotifyPropertyChanged Interface von Eigenschaftsänderungen zu benachrichtigen. Im Grunde ist meine Frage Welche der beiden ab .NET 4.5 eingeführten Methoden ist die effizientere Möglichkeit, Änderungen an Eigenschaften zu melden, und ob bei der Verwendung in WPF beides von Vorteil ist?Gibt es einen Vorteil der Verwendung des Namens des Operators anstelle des CallerMemberNameAttribute, um Änderungen der Eigenschaften in .NET 4.5.3 zu melden?

Hintergrund

Für jene nicht so vertraut mit diesem Thema, hier sind die drei wichtigsten Methoden. Die erste ist die ursprüngliche, fehleranfälliger Verfahren des einfachen String übergeben:

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

Die zweite Methode .NET 4,5 wurde eingeführt in; die 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)); 
    } 
} 

Die dritte und jüngste Methode war (oder wird bald) eingeführt in C# 6.0 als Teil .NET 4.5.3; die 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)); 
} 

Meine Vermutung wäre, dass die ursprünglichen, fehleranfällige Methode der einfach einen String übergeben die effizienteste wäre, da ich nur, dass die beiden anderen Methoden eine gewisse Form der Reflexion verwenden vorstellen kann. Ich bin jedoch sehr daran interessiert, herauszufinden, welche der beiden anderen Methoden effizienter ist und ob tatsächlich ein Unterschied zwischen der Verwendung des CallerMemberNameAttribute-Attributs und des nameof-Operators in einem WPF-Kontext besteht.

+0

„Die dritte und letzte Methode wurde (oder wird in Kürze) eingeführt in C# 6.0 als Teil von .NET 4.5.3; der Name des Operators "- genau genommen ist' nameof' ein [Sprachfeature] (https://github.com/dotnet/roslyn/wiki/New-Language-Features-in-C%23 -6) und nicht ein Teil des Frameworks. –

Antwort

24

Über Effizienz: CallerMemberNameAttribute, CallerMemberNameAttribute, nameof sind alle gleich, da die Zeichenfolge vom Compiler zur Kompilierungszeit injiziert wird. Es gibt keine Reflexion.

Wir können sehen, dass die Verwendung von TryRoslyn dass 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)); 
    } 
} 

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

zur Laufzeit Da alle Optionen sind einfach ein string mit dem WPF-Kontext kein Problem gibt.

Über Bequemlichkeit: CallerMemberNameAttribute erfordert, dass Sie einen optionalen Parameter haben, während nameof nicht der Fall ist, sondern nameof erfordert, dass Sie die Eigenschaft an, während CallerMemberNameAttribute nicht der Fall ist.

Ich prognostiziere, dass nameof würde sich als so populär erweisen, dass es viel einfacher wäre, es stattdessen zu verwenden.

+1

Warum wird nameof so beliebt sein? Es ist viel einfacher, CallerMemberNameAttribute wie einmal oder in der Regel mindestens weniger als nameof (die Sie in jeder Eigenschaft verwenden müssten) zu verwenden. Ich verstehe diese Trends nicht ... Kannst du das bitte erklären? –

+0

@ElMac nameof hat sich bereits in vielen Szenarien als beliebt erwiesen ... nicht nur um den Namen des Anrufers zu erhalten. Mehr Leute wissen es und verwenden es überall, so dass es einfacher ist, es auch hier zu verwenden. – i3arnon

6

Die CallerMemberNameAttribute kann nur für die aufgerufene Funktion verwendet werden, um den Namen der aufrufenden Funktion zu erhalten.

Der Operator nameof geht weit darüber hinaus. Es kann überall verwendet werden.

Wenn Sie Bindung nur im Rahmen von WPF Daten darüber zu folgern, nehmen Sie dieses Beispiel:

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