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?
risposta
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.
Che ironicamente è * più * codice rispetto all'altro meccanismo che utilizza 'CallerMemberName', e sfortunatamente non è così comico come' infoof'. –
'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. –
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. –
È 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).
Grazie per la risposta. Mi è piaciuto molto il tuo post di blog – Mehrad
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).
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));
}
}
}
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
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
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 –
ci sono già alternative alla magia prob stringa lem, solo per quello che sai. Anche se 'nameof' dovrebbe formalizzarlo. –
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. –
Grazie per l'informazione. – Mehrad