Eventos em C#
Tags: csharp, dotnet, tutorial, braziliandevs
Published: 2024-02-28 01:30:08

Eventos em C# são uma forma de permitir que objetos se comuniquem entre si. Eles são especialmente úteis em situações onde um objeto precisa notificar outros objetos sobre a ocorrência de alguma coisa. Essa abordagem promove um alto nível de desacoplamento entre os objetos, o que é uma prática recomendada na programação orientada a objetos.

### Definindo um Delegate
Antes de criar um evento, precisamos definir um delegate. O delegate funciona como uma assinatura para os métodos que podem ser associados ao evento. Ele define o tipo de método que pode ser registrado com o evento, incluindo os parâmetros que o método deve aceitar e o tipo de retorno.

```csharp
public delegate void FileDownloadedEventHandler(object source, FileEventArgs args);
```

### Disparando o Evento
A classe publicadora também deve fornecer um método protegido e virtual para disparar o evento. Este método é convencionalmente nomeado com o prefixo "On" seguido pelo nome do evento.

```csharp
protected virtual void OnFileDownloaded(FileEventArgs e)
{
    FileDownloaded?.Invoke(this, e);
}
```

### Escrevendo Event Handlers
Os assinantes (ou observadores) do evento escrevem manipuladores de eventos que correspondem à assinatura do delegate. Eles reagem ao evento com base na lógica definida dentro do manipulador.

```csharp
void OnFileDownloaded(object source, FileEventArgs e)
{
    Console.WriteLine($"File downloaded: {e.FileName}");
}
```

### Inscrevendo-se no Evento
Por fim, os assinantes registram seus event handlers com o evento para serem notificados quando o evento é disparado.

```csharp
fileDownloader.FileDownloaded += OnFileDownloaded;
```

### Benefícios da Programação Orientada a Eventos em **C#**

- Desacoplamento: Publicadores e assinantes são fracamente acoplados, permitindo uma maior flexibilidade no design da aplicação.
- Flexibilidade: É fácil adicionar ou remover assinantes sem modificar o código do publicador.
- Responsividade: Aplicações orientadas a eventos podem ser mais responsivas a ações do usuário.
- Escalabilidade: Facilita o design de aplicações complexas com interações escaláveis entre componentes.

### Melhores Práticas

- Use Argumentos de Evento Fortemente Tipados: Prefira usar classes de argumentos de evento customizadas em vez de EventArgs para passar informações adicionais.
- Segurança de Threads: Considere a segurança de threads ao disparar eventos em um ambiente multi-threaded.
- Evite Vazamentos de Memória: Remova a inscrição de eventos corretamente para evitar vazamentos de memória, especialmente em publicadores de longa duração.

## Exemplo de Código Completo
Agora, vamos integrar todos esses conceitos em um exemplo de código completo que simula o download de um arquivo, disparando um evento quando o download é concluído.

```csharp
using System;

// Definindo o delegate
public delegate void FileDownloadedEventHandler(object source, FileEventArgs e);

public class FileDownloader
{
    // Declarando o evento
    public event FileDownloadedEventHandler FileDownloaded;

    // Método para disparar o evento
    protected virtual void OnFileDownloaded(FileEventArgs e)
    {
        FileDownloaded?.Invoke(this, e);
    }

    // Simula o download de um arquivo
    public void DownloadFile(string fileName)
    {
        // Simula o processo de download
        Console.WriteLine("Downloading file...");

        // Dispara o evento após o download ser concluído
        OnFileDownloaded(new FileEventArgs { FileName = fileName });
    }
}

public class FileEventArgs : EventArgs
{
    public string FileName { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        var fileDownloader = new FileDownloader();

        // Inscrevendo-se no evento
        fileDownloader.FileDownloaded += OnFileDownloaded;

        // Inicia o download
        fileDownloader.DownloadFile("example.txt");
    }

    // Manipulador de evento
    static void OnFileDownloaded(object source, FileEventArgs e)
    {
        Console.WriteLine($"File downloaded: {e.FileName}");
    }
}
```

Este exemplo demonstra a criação de um sistema simples orientado a eventos, onde um FileDownloader notifica seus assinantes quando um arquivo é baixado, usando todos os conceitos abordados.