2014-12-12 8 views
6

stavo leggendo la nuova parola chiave nameof in C# 6. Voglio sapere come posso implementare INotifyPropertyChanged usando questa parola chiave, quali sono i prerequisiti (ovviamente diversi da C# 6) e come influenzerà le prestazioni del mio MVVM applicazione?Come implementare INotifyPropertyChanged con il nome di invece di stringhe magiche?

+1

ci sono già alternative alla magia prob stringa lem, solo per quello che sai. Anche se 'nameof' dovrebbe formalizzarlo. –

+1

No, non l'ho mai fatto notare. Ti stavo semplicemente informando nel caso in cui stavi aspettando qualcosa che non è stato ancora rilasciato per risolvere qualcosa che potresti risolvere oggi. È anche utile per * altri * visitatori in quanto questa domanda non è solo a vostro vantaggio. –

+0

Grazie per l'informazione. – Mehrad

risposta

9

Sarebbe simile a questa:

public string Foo 
{ 
    get 
    { 
     return this.foo; 
    } 
    set 
    { 
     if (value != this.foo) 
     { 
      this.foo = value; 
      OnPropertyChanged(nameof(Foo)); 
     } 
    } 
} 

Il nameof(Foo) verrà sostituita con la stringa "pippo" al momento della compilazione, quindi dovrebbe essere molto performante. Questa non è una riflessione.

+0

Che ironicamente è * più * codice rispetto all'altro meccanismo che utilizza 'CallerMemberName', e sfortunatamente non è così comico come' infoof'. –

+2

'CallerMemberName' è disponibile solo in .NET 4.5. 'Nameof' viene fornito con il compilatore C# in modo da essere ancora in grado di mirare a framework .NET meno recenti. –

+0

Vero, non avevo pensato a quel beneficio. Ma interessante, "CallerMemberName' è anche una [funzione basata sul compilatore] (http://stackoverflow.com/questions/13381917/is-the-callermembername-attribute-in-4-5-able-to-be-faked) così può essere tolto dalla dipendenza .NET 4.5. Personalmente cambierei in 'nameof' per l'altro motivo che il codice è più esplicito e meno è nascosto dalla prospettiva del chiamante. –

6

È solo una questione di utilizzare nameof() anziché la stringa magica. L'esempio che segue è dal mio blog article sul tema:

private string currentTime; 

public string CurrentTime 
{ 
    get 
    { 
     return this.currentTime; 
    } 
    set 
    { 
     this.currentTime = value; 
     this.OnPropertyChanged(nameof(CurrentTime)); 
    } 
} 

Dal momento che è evaluated at compile-time, è più performante di qualsiasi delle alternative correnti (che sono anche menzionati in questo articolo del blog).

+0

Grazie per la risposta. Mi è piaciuto molto il tuo post di blog – Mehrad

3

Ecco un esempio di codice completo di una classe utilizzando il nuovo zucchero C# 6.0:

public class ServerViewModel : INotifyPropertyChanged { 
    private string _server; 
    public string Server { 
     get { return _server; } 
     set { 
      _server = value; 
      OnPropertyChanged(nameof(Server)); 
     } 
    } 

    private int _port; 
    public int Port { 
     get { return _port; } 
     set { 
      _port = value; 
      OnPropertyChanged(nameof(Port)); 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
    protected void OnPropertyChanged(string propertyName) => 
     PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
} 

Con questo, si ottiene l'operatore nameof(), il nulla-condizionale dell'operatore ?., e una funzione di espressione di corpo (la OnPropertyChanged definizione).

3

ho trovato è molto più facile da usare PropertyChanged.Fody come si finisce con meno errori e un inferno di molto codice più pulito, vedi - https://github.com/Fody/PropertyChanged

Tutto quello che dovete fare è etichettare la vostra classe con ImplementPropertyChanged attributo:

[ImplementPropertyChanged] 
public class Person 
{   
    public string GivenNames { get; set; } 
    public string FamilyName { get; set; } 

    public string FullName 
    { 
     get 
     { 
      return string.Format("{0} {1}", GivenNames, FamilyName); 
     } 
    } 
} 

E dopo la generazione che si trasforma in a:

public class Person : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    string givenNames; 
    public string GivenNames 
    { 
     get { return givenNames; } 
     set 
     { 
      if (value != givenNames) 
      { 
       givenNames = value; 
       OnPropertyChanged("GivenNames"); 
       OnPropertyChanged("FullName"); 
      } 
     } 
    } 

    string familyName; 
    public string FamilyName 
    { 
     get { return familyName; } 
     set 
     { 
      if (value != familyName) 
      { 
       familyName = value; 
       OnPropertyChanged("FamilyName"); 
       OnPropertyChanged("FullName"); 
      } 
     } 
    } 

    public string FullName 
    { 
     get 
     { 
      return string.Format("{0} {1}", GivenNames, FamilyName); 
     } 
    } 

    public virtual void OnPropertyChanged(string propertyName) 
    { 
     var propertyChanged = PropertyChanged; 
     if (propertyChanged != null) 
     { 
      propertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 
+0

Assistente fantastico.Io uso un sacco di POCO per lo scambio di dati con ServiceStack, e questo mi permette di mantenerli super-semplici (in termini di codice). – jklemmack

+0

Questa risposta sarebbe meglio se includessi una spiegazione di cosa sia Fody. Inoltre, il codice trasformato contiene ancora stringhe magiche, che è ciò che l'OP vuole evitare. Se il nome di una proprietà viene modificato, Fody aggiornerà automaticamente anche le stringhe? – kmote

+0

Quindi fody è un post build il weaver in modo che cambi il tuo codice dopo la sua creazione ... Le stringhe magiche verranno aggiornate automaticamente dopo ogni build –

Problemi correlati