Delegados em C# e Suas Aplicações

Definição de Delegado

Em C#, um delegado é um tipo seguro que encapsula referências a métodos com assinaturas específicas. Ele permite tratar funções como parâmetros ou variáveis, facilitando a delegação de tarefas. De forma simplificada, um delegado funciona como um ponteiro de função tipado, permitindo a passagem de métodos como argumentos e armazenamento de referências a funções. Pode-se considerá-lo como uma interface com um único método, onde instâncias do delegado implementam essa interface.

Cenários de Uso

1. Tratamento de Eventos: Em aplicações C#, eventos são frequentemente implementados usando delegados. Por exemplo, em uma interface gráfica com botões, o evento de clique é associado a um delegado que invoca o método de tratamento correspondente.

2. Métodos de Retorno (Callbacks): Delegados são ideais para callbacks, como em operações assíncronas onde se deseja notificar a conclusão de uma tarefa, como o download de dados TCP.

3. Multicast (Difusão Múltipla): Delegados podem referenciar vários métodos, permitindo a invocação simultânea de múltiplas funções, útil para cenários como notificações em massa.

4. Operações em Coleções: Delegados são usados em consultas LINQ ou métodos como ForEach para filtrar ou manipular dados em coleções, como listas.

Utilização Básica de Delegados

Primeiro, declare um delegado com a assinatura desejada:

delegate void ProcessadorSimples(int valor); // Delegado sem retorno e com parâmetro inteiro

Outros exemplos de declaração:

public delegate void AcaoSemParametros();
public delegate void AcaoComParametros(int x, int y);
public delegate int CalculoComRetorno(int a, int b);

Para instanciar um delegado, associe-o a um método compatível:

ChamadorAssincrono chamador = new ChamadorAssincrono(MetodoAssincronoExemplo);

/// <summary>
/// Método associado ao delegado
/// </summary>
static string MetodoAssincronoExemplo(int tempo, out int threadId)
{
    Stopwatch cronometro = new Stopwatch();
    cronometro.Start();
    Console.WriteLine("Início do processamento assíncrono");
    for (int i = 0; i < 5; i++)
    {
        Thread.Sleep(tempo);
        Console.WriteLine($"Iteração {i}");
    }
    cronometro.Stop();
    threadId = Thread.CurrentThread.ManagedThreadId;
    return $"Tempo decorrido: {cronometro.ElapsedMilliseconds}ms";
}

É possível usar expressões lambda para métodos anônimos:

ChamadorAssincrono2 chamadorLambda = new ChamadorAssincrono2((tempo) =>
{
    Stopwatch cronometro = new Stopwatch();
    cronometro.Start();
    Console.WriteLine("Processamento com lambda iniciado");
    for (int i = 0; i < 5; i++)
    {
        Thread.Sleep(tempo);
        Console.WriteLine($"Lambda iteração {i}");
    }
    cronometro.Stop();
    return $"Duração: {cronometro.ElapsedMilliseconds}ms";
});

Para delegdaos multicast, que executam múltiplos métodos:

internal class ExemploMulticast
{
    delegate string ProcessadorMulti(int valor);

    static void Main(string[] args)
    {
        Console.WriteLine("Teste de delegado multicast");
        ProcessadorMulti processador = new ProcessadorMulti(ProcessarDados1);
        processador += ProcessarDados2; // Adiciona segundo método
        processador.Invoke(500); // Executa ambos em sequência
        Console.WriteLine("Métodos adicionados são chamados na ordem");
        processador -= ProcessarDados2; // Remove segundo método
        Console.WriteLine("Após remoção, apenas o primeiro é executado");
        processador.Invoke(500);
    }

    static string ProcessarDados1(int tempo)
    {
        // Simula processamento de dados
        Thread.Sleep(tempo);
        return "Dados processados pelo método 1";
    }

    static string ProcessarDados2(int tempo)
    {
        // Simula processamento adicional
        Thread.Sleep(tempo);
        return "Dados processados pelo método 2";
    }
}

Delegados Integrados: Action e Func

Action: Represenat um delegado sem retorno, podendo ter zero ou até 16 parâmetros genéricos. Exemplo de uso:

Action acao = new Action(MetodoAcao);
acao.Invoke();

void MetodoAcao() { Console.WriteLine("Execução via Action"); }

Func: Representa um delegado com retorno, suportando zero ou até 16 parâmetros genéricos. Exemplo:

Func<int, int, int> soma = new Func<int, int, int>(CalcularSoma);
int resultado = soma(3, 5);
Console.WriteLine($"Resultado: {resultado}");

int CalcularSoma(int a, int b) => a + b;

Tags: C# delegados multicast Action Func

Publicado em 6-8 05:35 por Thomas