Che l’implementazione di INotifyPropertyChanged porti a scrivere del codice non propriamente ‘bello’ e funzionale è ormai scontato, personalmente non è mai stato un problema, bisogna però avere l’accortezza (e questo non sempre avviene) di rinominare il nome della funzione passato nell’evento quando si fa refactoring: soluzione decisamente molto “Code Smelling”.
1: public class MyClass:INotifyPropertyChanged
2: {
3: string userName;
4:
5: public string UserName
6: {
7: get { return userName; }
8: set
9: {
10: userName = value;
11: this.OnPropertyChanged("UserName");
12: }
13: }
14:
15: protected void OnPropertyChanged(string propertyName)
16: {
17: if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
18: }
19:
20: public event PropertyChangedEventHandler PropertyChanged;
21: }
Ovviamente esistono diverse alternative a questo problema, a partire da quella proposta da Matteo per arrivare a quella proposta da Mauro entrambe soluzioni eleganti ma che personalmente ritengo poco leggibili.
Relativamente a questo problema, ieri sulla lista dei WPF Disciples c’è stato un interessante thread che ha portato ad una soluzione che ritengo possa essere il giusto compromesso tra ‘smelling’, leggibilità e performances. Su quest’ultimo aspetto bisogna prestare particolare attenzione perchè tutte le soluzioni generano un overhead che in alcuni casi potrebbe sconsigliarne l’utilizzo.
La soluzione proposta da Karl Shifflet è la seguente:
1: public string UserName
2: {
3: get { return userName; }
4: set
5: {
6: userName = value;
7: this.OnPropertyChanged(MethodBase.GetCurrentMethod().Name.Remove(0, 4));
8: }
9: }
La soluzione funziona anche con Silverlight e ha un overhead abbastanza contenuto:
A questo indirizzo trovate il post di Karl che contiene un progetto di esempio, benchmarks e svariate alternative.
Nota: Questa soluzione non è stata provata in situazione di codice offuscato / inlining, se qualcuno ha la possibilità di provarla in tale contesto e vuol far conoscere i risultati ben venga.