Delagates Func, Action e Predicate

Sumário

delegateFuncActionPredicate

Veja o índice completo do tópico “Delegate”

Olá 🙂

Nos artigos anteriores vimos o uso do delegates em eventos, para criar chamadas estilo callback, como invocar métodos e como criar seus delegates.

E continuando nosso assunto sobre delegates, iremos falar sobre três importantes delegates dentro do C#, Func, Action e Predicate.

Func & Action

Nos artigos anteriores criamos uma calculadora usando delegate, aproveitando aquele exemplo, iremos reescrever nossa calculadora usando os delegates Func<> e Action<>.

note-taking A única diferença entre estes dois delegates é o retorno, enquanto no Func<> você é obrigado a informar o tipo de retorno esperado, o Action não retorna nada, é um void.

Os dois delegates possuem ao todo 16 parâmetros de entrada cada um e o Func<> mais um de retorno.
Eu nunca precisei usar mais que 3, se começar a usar muitos parâmetros, reveja seu código.

Chega de papo e mãos à obra

Abaixo o código completo da calculadora usando estes dois delegates.

using System;

namespace FuncEAction
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            Console.Title = "Calculadora delegate";
            //Criando o ponteiro para o delegate, iniciamos com null, pois não sabemos qual operação iremos realizar.
            Func<double, double, double> handler = null;
            //Ação que será executada
            Action action = null;

            //while(true) ... Yes ...
            while(true)
            {
                string operacao = LerOperacao();

                //de acordo com a operação utilizada, iremos istanciar o nosso delegate e executar o método associado
                switch(operacao)
                {
                    case "+":
                        handler = Somar;
                        break;
                    case "-":
                        handler = Subtrair;
                        break;
                    case "*":
                        handler = Multiplicar;
                        break;
                    case "/":
                        handler = Dividir;
                        break;
                    case "s":
                        action = Exit;
                        break;
                    case "c":
                        action = Clear;
                        break;
                    default:
                        Console.WriteLine("Operação não implementada.");
                        continue;
                }

                if(action != null)
                {
                    //invocar a ação do mal
                    action();
                    action = null;
                    continue;
                }

                double x = LerNumero("primeiro");
                double y = LerNumero("segundo");

                //Executa o método associado
                Console.WriteLine($"\r\nO resultado da operação {x:N2} {operacao} {y:N2} é {handler(x, y):N2}");

                Console.ReadKey();
            }
        }

        #region Métodos de leitura

        private static string LerOperacao()
        {
            string validas = "+-*/cs";
            string result = "";

            do
            {
                DrawMenu();
                result = Console.ReadKey().KeyChar.ToString();

                if(!validas.Contains(result))
                {
                    Console.WriteLine("\r\nInforme uma operação válida.");
                    result = "";
                    Console.ReadKey();
                }
            } while(String.IsNullOrWhiteSpace(result));

            return result;
        }

        private static double LerNumero(string text)
        {
            double result = 0;

            do
            {
                Console.Clear();
                Console.WriteLine($"Informe o {text} número da operação.");
                string numero = Console.ReadLine();

                if(!double.TryParse(numero, out result))
                {
                    Console.WriteLine("\r\nInforme um número válido.");
                    Console.ReadKey();
                }
            } while(result == 0);

            return result;
        }

        #endregion Métodos de leitura

        #region Métodos de operação

        private static double Somar(double x, double y)
        {
            return x + y;
        }

        private static double Dividir(double x, double y)
        {
            return x / y;
        }

        private static double Multiplicar(double x, double y)
        {
            return x * y;
        }

        private static double Subtrair(double x, double y)
        {
            return x - y;
        }

        #endregion Métodos de operação

        #region Métodos de ação

        private static void Exit()
        {
            Environment.Exit(0);
        }

        private static void Clear()
        {
            Console.Clear();
        }

        private static void DrawMenu()
        {
            Console.WriteLine("Informe a operação desejada:");
            Console.WriteLine("(+) para Somar.");
            Console.WriteLine("(-) para Subtrair.");
            Console.WriteLine("(/) para Dividir.");
            Console.WriteLine("(*) para Multiplicar.");
            Console.WriteLine("(c) para Limpar o log.");
            Console.WriteLine("(s) para Sair.");
        }

        #endregion Métodos de ação
    }
}

Predicate

O tipo Predicate é um delegate especial que possui apenas um parâmetro de entrada e retorna um booleano.
Deve ser utilizado quando precisamos informar uma condição para que a ação seja executada. O nosso predicado, pode executar quantas situações forem necessárias para satisfazer a condição.

No código abaixo, iremos ver um exemplo de uso do Predicate e do Action por classes do C#.

Repare que iremos usar a classe “Array

    internal class Program
    {
        private static void Main(string[] args)
        {
            //Array com o nome dos países
            string[] countries ={
                    "Afeganistão","África do Sul","Akrotiri","Albânia","Alemanha","Andorra","Angola","Anguila","Antártida","Antígua e Barbuda","Antilhas","Arábia Saudita","Arctic Ocean","Argélia","Argentina","Arménia","Aruba","Ashmore andCartier Islands","Atlantic Ocean","Austrália","Áustria","Azerbaijão","Baamas","Bangladeche","Barbados","Barém","Bélgica","Belize","Benim","Bermudas","Bielorrússia","Birmânia","Bolívia","Bósnia e Herzegovina","Botsuana","Brasil","Brunei","Bulgária","Burquina Faso","Burúndi","Butão","Cabo Verde","Camarões","Camboja","Canadá","Catar","Cazaquistão","Chade","Chile","China","Chipre","ClippertonIsland","Colômbia","Comores","Congo-Brazzaville","Congo-Kinshasa","Coral Sea Islands","Coreia do Norte","Coreia doSul","Costa do Marfim","Costa Rica","Croácia","Cuba","Dhekelia","Dinamarca","Domínica","Egipto","EmiratosÁrabes Unidos","Equador","Eritreia","Eslováquia","Eslovénia","Espanha","Estados Unidos","Estónia","Etiópia","Faroé","Fiji","Filipinas","Finlândia","França","Gabão","Gâmbia","Gana","GazaStrip","Geórgia","Geórgia do Sul e Sandwich do Sul","Gibraltar","Granada","Grécia","Gronelândia","Guame","Guatemala","Guernsey","Guiana","Guiné","Guiné Equatorial","Guiné-Bissau","Haiti","Honduras","Hong Kong","Hungria","Iêmen","Ilha Bouvet","Ilha do Natal","Ilha Norfolk","Ilhas Caimão","Ilhas Cook","Ilhas dos Cocos","Ilhas Falkland","Ilhas Heard e McDonald","Ilhas Marshall","Ilhas Salomão","Ilhas Turcas e Caicos","Ilhas Virgens Americanas","Ilhas VirgensBritânicas","Índia","Indian Ocean","Indonésia","Irão","Iraque","Irlanda","Islândia","Israel","Itália","Jamaica","Jan Mayen","Japão","Jersey","Jibuti","Jordânia","Kuwait","Laos","Lesoto","Letónia","Líbano","Libéria","Líbia","Listenstaine","Lituânia","Luxemburgo","Macau","Macedónia","Madagáscar","Malásia","Malávi","Maldivas","Mali","Malta","Man, Isle of","Marianas do Norte","Marrocos","Maurícia","Mauritânia","Mayotte","México","Micronésia","Moçambique","Moldávia","Mónaco","Mongólia","Monserrate","Montenegro","Mundo","Namíbia","Nauru","Navassa Island","Nepal","Nicarágua","Níger","Nigéria","Niue","Noruega","Nova Caledónia","Nova Zelândia","Omã","Pacific Ocean","Países Baixos","Palau","Panamá","Papua-Nova Guiné","Paquistão","Paracel Islands","Paraguai","Peru","Pitcairn","Polinésia Francesa","Polónia","Porto Rico","Portugal","Quénia","Quirguizistão","Quiribáti","Reino Unido","República Centro-Africana","República Checa","República Dominicana","Roménia","Ruanda","Rússia","Salvador","Samoa","Samoa Americana","Santa Helena","Santa Lúcia","São Cristóvão e Neves","São Marinho","São Pedro e Miquelon","São Tomé e Príncipe","São Vicente e Granadinas","Sara Ocidental","Seicheles","Senegal","Serra Leoa","Sérvia","Singapura","Síria","Somália","Southern Ocean","Spratly Islands","Sri Lanca","Suazilândia","Sudão","Suécia","Suíça","Suriname","Svalbard e Jan Mayen","Tailândia","Taiwan","Tajiquistão","Tanzânia","Território Britânico do Oceano Índico","Territórios Austrais Franceses","Timor Leste","Togo","Tokelau","Tonga","Trindade e Tobago","Tunísia","Turquemenistão","Turquia","Tuvalu","Ucrânia","Uganda","União Europeia","Uruguai","Usbequistão","Vanuatu","Vaticano","Venezuela","Vietname","Wake Island","Wallis e Futuna","West Bank","Zâmbia","Zimbabué"
                };

            //imprimir array
            Console.WriteLine("\r\nImprimindo países\r\n");
            Action<string> printArray = (item) => { Console.WriteLine(item); };
            Array.ForEach(countries, printArray);

            //encontrar um último da letra M
            Console.WriteLine("\r\nÚltimo com a letra M\r\n");
            Predicate<string> findLastM = (item) =>
            {
                return item.StartsWith("M", StringComparison.InvariantCultureIgnoreCase);
            };
            Console.WriteLine($"O último com a letra M é {Array.FindLast(countries, findLastM)}");

            //imprimir todos que tem a letra k
            Console.WriteLine("\r\nTodos que tem a letra K\r\n");
            Predicate<string> hasK = (item) =>
            {
                return item.Contains("k");
            };

            string[] ks = Array.FindAll(countries, hasK);
            Array.ForEach(ks, printArray);

            Console.ReadKey();
        }
    }
question Lindo isso, mas eu realmente vou usar?

Sim, vai. Aguarde novidades nos próximos capítulos, quando entrarmos no assunto expressões lambda.

 


É isso ai pessoal 🙂
Até o próximo
♦ Marcelo

Marcelo

Nascido em Juruaia/MG em uma fazenda de criação de búfalos, e residindo na região Sul do Brasil.
Trabalha com desenvolvimento de aplicações desde os 17 anos. Atualmente é Arquiteto Organizacional na Unimake Software.
Para saber mais ... http://desenvolvedores.net/marcelo
[]'s

Você vai gostar de...

Postagens populares.

Deixe um comentário

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.