2015-02-08 12 views
18

Con l'avvento di .NET 4.5.3, gli sviluppatori WPF ora hanno tre (o più) modi per notificare il INotifyPropertyChanged Interface di modifiche alle proprietà. Fondamentalmente, la mia domanda è Quale dei due metodi introdotti da.NET 4.5 in poi è il modo più efficace per notificare le modifiche alle proprietà e se in entrambi i casi ha qualche vantaggio quando viene utilizzato in WPF?C'è qualche vantaggio nell'usare l'operatore nameof invece del CallerMemberNameAttribute per notificare le modifiche alle proprietà in .NET 4.5.3?

Sfondo

Per chi non ha molta familiarità con questo argomento, ecco i principali tre metodi. La prima è la più errore metodo inclini originali semplicemente passando una stringa:

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

Il secondo metodo è stato introdotto in .NET 4.5; il 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)); 
    } 
} 

Il terzo e più recente metodo è stato (o sarà presto) ha introdotto in C# 6.0 come parte di .NET 4.5.3; il 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)); 
} 

La mia ipotesi è che il più errore di metodo inclini originale semplicemente passando una stringa sarebbe la più efficace, come posso solo immaginare che gli altri due metodi utilizzano una qualche forma di riflessione. Tuttavia, sono davvero curioso di scoprire quale degli altri due metodi sia più efficiente e se ci sia effettivamente qualche differenza tra l'uso dell'attributo CallerMemberNameAttribute e l'operatore nameof in un contesto WPF.

+0

"Il terzo e più recente metodo è stato (o sarà presto) ha introdotto in C# 6.0 come parte di .NET 4.5.3, il nome di Operator "- strettamente parlando" nameof "è una [lingua] (https://github.com/dotnet/roslyn/wiki/New-Language-Features-in-C%23 -6) e non una parte del quadro. –

risposta

24

Informazioni sull'efficienza: l'utilizzo di una stringa direttamente, CallerMemberNameAttribute, nameof è esattamente lo stesso poiché la stringa viene iniettata dal compilatore in fase di compilazione. Non c'è nessuna riflessione in questione.

possiamo vedere che utilizzando TryRoslyn che 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)); 
    } 
} 

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

Dal momento in fase di esecuzione tutte le opzioni sono semplicemente un string non c'è nessun problema con il contesto WPF.

A proposito di comodità: CallerMemberNameAttribute richiede di avere un parametro opzionale, mentre nameof ma non nameof richiede di specificare la proprietà, mentre CallerMemberNameAttribute non lo fa.

Prevedo che nameof risulterebbe così popolare che sarebbe molto più semplice utilizzarlo.

+1

Perché il nome di risulta essere così popolare? È molto più semplice usare CallerMemberNameAttribute come una volta, o di solito almeno meno di nameof (che dovresti usare in ogni proprietà). Non capisco queste tendenze ... Puoi spiegare per favore? –

+0

@ElMac nameof si è già rivelato popolare in molti scenari ... non solo per ottenere il nome del chiamante. Più persone lo sanno e lo usano dappertutto, quindi è più semplice utilizzarlo anche qui. – i3arnon

6

CallerMemberNameAttribute può essere utilizzato solo sulla funzione chiamata per ottenere il nome della funzione chiamante.

L'operatore nameof va ben oltre. Può essere utilizzato ovunque.

Se si vuole ragionare su di esso solo nel campo di applicazione dei dati WPF vincolanti, prendere questo esempio:

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