Back-End

11 dez, 2018

C# – Usando delegates na prática: ordenação de objetos

100 visualizações
Publicidade

Neste artigo vamos aplicar o conceito de delegates, implementando um algoritmo para ordenação de strings. Vamos supor que você precise criar um pequeno programa para realizar a ordenação, a princípio de nomes de pessoas, a partir de seu nome completo, ordenando pelo primeiro nome.

Você pode usar a abordagem tradicional e usar métodos, definindo um algoritmo que realiza a ordenação, manipulando os valores das variáveis e chamando os métodos diretamente.

Neste caso, você pode implementar uma instrução if/then/else ou switch para manipular tipos conhecidos, mas isso limitaria muito a aplicabilidade do seu algoritmo e ainda exigiria a sobrecarga para determinar o tipo.

Outra alternativa seria que todos os tipos implementassem uma interface que declarasse um método comum que seu algoritmo chamaria, e essa seria uma solução mais robusta.

No entanto, se você quiser criar um algoritmo mais flexível e reutilizável que permita implementar diferentes funcionalidades conforme a necessidade – e também já prevendo a ordenação de diferentes tipos de dados, e não apenas strings -, uma solução mais elegante seria usar Delegates.

Neste caso, você pode passar um delegate ao seu algoritmo e deixar o método contido, ao qual o delegado se refere, executar a operação de comparação e ordenação. É isso que faremos neste artigo.

Vamos implementar uma ordenação de objetos mostrando como os delegates podem ser úteis.

Recursos usados:

  • Visual Studio 2017 Community

Criando o projeto no VS 2017 Community

Crie um novo projeto do tipo Console com o nome CSharp_DelegateOrdena, e a seguir, crie uma classe chamada NomeCompleto com o código abaixo:

Nesta classe estamos usando o método Compare() da classe String(), que compara dois objetos String especificados, ignorando ou respeitando as maiúsculas e minúsculas, e retorna um inteiro, que indica sua posição relativa na ordem de classificação conforme mostra a tabela abaixo:

public static int Compare(string strA, string strB, bool ignoreCase)

A classe NomeCompleto() retorna o nome seguido do sobrenome.

Agora criaremos outra classe chamada TestaDelegate() para poder testar o Delegate com o código abaixo:

Nesta classe definimos cinco nomes completos no construtor e criamos o método Ordenar, que é referenciado pelo Delegate e faz a ordenação dos objetos. O método ImprimiNomes() apenas exibe os nomes no Console.

Agora podemos testar a nossa implementação no arquivo Program.cs, declarando um delegate que poderá referenciar qualquer método que receba como argumento dois objetos e retorne um int.

Para poder usar o delegate, temos que instanciá-lo e, ao instanciar o delegate, apontamos sua referência para o método CompararNome da classe NomeCompleto, que possui a assinatura esperada pelo Delegate:

Aqui temos uma declaração do delegate que define a assinatura de um método ao qual esse delegate pode se referir. Esse é o método CompararNome da classe NomeCompleto conforme mostra o código a seguir:

       // realiza o tratamento do metodo Delegate
        public static int CompararNome(object nome1, object nome2)
        {
            string n1 = ((NomeCompleto)nome1).Nome;
            string n2 = ((NomeCompleto)nome2).Nome;
            if (String.Compare(n1, n2) > 0)
            {
                return 1;
            }
            else if (String.Compare(n1, n2) < 0)
            {
                return -1;
            }
            else
            {
                return 0;
            }
        }

O método do manipulador do delegate para o delegate Comparador, pode ter qualquer nome, mas deve ter o primeiro parâmetro do tipo object, o segundo parâmetro do tipo object e deve retornar um tipo int.

Observe que a instância do delegate, cmp, é usada como um parâmetro para o método Ordenar:

testaDel.Ordenar(cmp)

Usando essa técnica, qualquer método manipulador do delegate pode ser passado para o método Ordenar() em tempo de execução. Ou seja, você poderia definir um de método chamado CompararPrimeiroNome(), instanciar uma nova instância de delegate Comparador com ele e passar o novo delegate para o método Ordenar().

Executando o projeto iremos obter:

Simples assim!

Pegue o projeto completo aqui: CSharp_DelegateOrdena.zip