C# - Implementando INotifyPropertyChanged - II


Hoje vamos continuar a mostrar como melhorar o seu código na implementação da interface INotifyPropertyChanged.

No artigo anterior otimizamos a implementação da interface INotifyPropertyChanged e chegamos ao seguinte resultado:

A classe Cliente  e a classe base NotifyBase :

classe Cliente
classe NotifyBase

Agora imagine que a nossa classe Cliente tenha além da propriedade Nome mais dez propriedades.

Neste cenário teríamos que usar o seguinte código mostrado abaixo apenas para a propriedade Endereco:

 public class Cliente : NotifyBase
    {
        private string _nome;
        public string Nome
        {
            get
            {
                return _nome;
            }
            set
            {
                _nome = value;
                OnPropertyChanged();
            }
        }
        private int _endereco;
        public int Endereco
        {
            get { return _endereco; }
            set {
                _endereco = value;
             OnPropertyChanged();
            }
        }
        //...e nas demais propriedades
    }

Teríamos que repetir a chamada e atribuição do valor da propriedade no método Set em todas as outras propriedades.

Mas será que não podemos melhorar esse código substituindo as duas linhas de código por uma única declaração ?

Vamos fazer isso a seguir...

Implementando o método SetProperty

Vamos criar na nossa classe base o método SetProperty() que retorna bool e que chama o método OnPropertyChanged():

protected bool SetProperty()
{
            OnPropertyChanged();
            return true;
 }

Ajustando o código para chamar o método OnPropertyChanged() de qualquer lugar teremos:

protected bool SetProperty([CallerMemberName]string propertyName = null)
{
            OnPropertyChanged(propertyName);
            return true;
}

Mas precisamos passar o nome da propriedade que esta sendo alterada e do seu valor.

Vamos passar o nome da propriedade via referência (ref) e o valor atribuido como uma string para começar:

protected bool SetProperty(ref string _backField, string value , [CallerMemberName]string propertyName = null)
{
              _backField = value;
            OnPropertyChanged(propertyName);
            return true;
}

Agora com essas alterações podemos alterar o código da classe Cliente :

 public class Cliente : NotifyBase
 {
        private string _nome;
        public string Nome
        {
            get
            {
                return _nome;
            }
            set
            {
                _nome = value;
                OnPropertyChanged();
            }
        }
        private int _endereco;
        public int Endereco
        {
            get { return _endereco; }
            set {
                SetProperty(ref _endereco, value) 
            }
        }
 }

Agora para completar vamos fazer o nosso método SetProperty() ser um método genérico e não funcionar apenas para string.

Além disso vamos incluir uma verificação para ver se o valor da propriedade alterada possui o mesmo valor.  Neste caso não precisamos alterar nada.

Nossa implementação final ficou assim:

Classe NotifyBase
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace ImplementandoINotifyPropertyChanged
{
    public abstract class NotifyBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged([CallerMemberName]string propertyName = null)
        {
           PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        protected bool SetProperty<T>(ref T _backField, T value, [CallerMemberName]string propertyName = null)
        {
            if (EqualityComparer<T>.Default.Equals(_backField, value))
            {
                return false;
            }
            _backField = value;
            OnPropertyChanged(propertyName);
            return true;
        }
    }
}	
Classe Cliente
 public class Cliente : NotifyBase
 {
        private string _nome;
        public string Nome
        {
            get
            {
                return _nome;
            }
            set
            {
                SetProperty(ref _nome, value) 
            }
        }
        private int _endereco;
        public int Endereco
        {
            get { return _endereco; }
            set {
                SetProperty(ref _endereco, value) 
            }
        }
 }

Agora basta herdar da nossa classe abstrata NotifyBase, e, fazer a notificação sem precisar passar o nome da propriedade que será inferido pelo atributo CallerMemberName

Além disso na classe que herda da nossa classe base agora basta usar apenas o método SetProperty() para atribuir o valor e chamar o evento OnPropertyChanged().

O código da nossa classe Cliente fiou bem mais enxuto e bem mais simples, não é mesmo ???

Pegue o código aqui: ImplementandoINotifyPropertyChanged2.zip

"E também todos os que piamente querem viver em Cristo Jesus padecerão perseguições.
Mas os homens maus e enganadores irão de mal para pior, enganando e sendo enganados."
2 Timóteo 3:12,13

Veja os Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Quer aprender C# ??

Quer aprender os conceitos da Programação Orientada a objetos ?

Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ?

Quer aprender a criar aplicações Web Dinâmicas usando a ASP .NET MVC 5 ?

 

  Gostou ?   Compartilhe no Facebook   Compartilhe no Twitter

 

Referências:


José Carlos Macoratti