Eventos C#

Resumo : neste tutorial, você aprenderá sobre eventos C# e como usá-los de maneira eficaz para projetar aplicativos de baixo acoplamento.

Introdução aos eventos C#

Eventos são algo que ocorre em um programa. Os eventos permitem que uma classe ou objeto notifique outras classes ou objetos quando algo ocorre.

  • A classe que gera (ou envia) o evento é chamada de editora .
  • As classes que recebem (ou tratam) o evento são chamadas de assinantes . E o método das classes que tratam o evento costuma ser chamado de manipuladores de eventos.

Esse padrão é conhecido como editor/assinante . Nesse padrão, o publicador determina quando acionar o evento e os assinantes decidem como lidar com o evento.

Tecnicamente, um evento possui um delegado encapsulado . Na verdade, um evento é como um delegado mais simples. Vejamos um exemplo de uso de eventos.

Suponha que você tenha uma classe chamada Ordercom um método Create()que cria uma nova ordem:

class Order
{
    public void Create()
    {
        Console.WriteLine("Order created");
    }
}Linguagem de código:  C#  ( cs )

E outras duas classes que enviam email e SMS:

class Email 
{
    public static void Send()
    {
        Console.WriteLine("Send an email");
    }
}

class SMS
{
    public static void Send()
    {
        Console.WriteLine("Send an SMS");
    }
}Linguagem de código:  C#  ( cs )

Quando um pedido é criado, você deseja enviar um e-mail e SMS ao cliente. Para fazer isso, você pode criar o seguinte código:

class Order
{
    public void Create()
    {
        Console.WriteLine("Order was created");
        Email.Send();
        SMS.Send();
    }
}Linguagem de código:  C#  ( cs )

Posteriormente, se quiser realizar outras tarefas quando um pedido for criado, será necessário modificar o Create()método. Além disso, a classe Order depende das classes Email e SMS, o que não é um bom design.

Para resolver isso, você pode usar o padrão editor/assinante:

  • A Orderclasse é a editora.
  • As classes Emaile SMSsão os assinantes.

Quando um pedido for criado, o Orderobjeto notificará as classes Emaile SMSpara enviar um e-mail e SMS.

Declarando um evento

O seguinte declara o OnCreatedevento quando um pedido é criado:

delegate void OrderEventHandler();

class Order
{
    public event OrderEventHandler OnCreated;

    public void Create()
    {
        Console.WriteLine("Order created");
    }
}Linguagem de código:  C#  ( cs )

Como funciona.

Primeiro, defina um tipo de delegado para o evento:

delegate void OrderEventHandler();Linguagem de código:  C#  ( cs )

Segundo, declare um evento associado ao tipo delegado:

public event OrderEventHandler OnCreated;Linguagem de código:  C#  ( cs )

Como um evento é membro de uma classe, você precisa declará-lo dentro da classe. Neste exemplo, o evento é público para que outras classes possam registrar manipuladores de eventos nele. Além disso, os manipuladores de eventos devem corresponder ao tipo de delegado associado ao evento.

Levantando um evento

Gerar um evento é o mesmo que invocar um método. Um evento que não possui manipuladores de eventos é nulo. Portanto, antes de gerar um evento, você precisa compará-lo com null.

O seguinte gera o OnCreatedevento dentro do Create()método:

class Order
{
    public event OrderEventHandler OnCreated;

    public void Create()
    {
        Console.WriteLine("Order created");
        
        if(OnCreated != null)
        {
            OnCreated();
        }
    }
}Linguagem de código:  C#  ( cs )

Inscrever-se em um evento

Inscrever-se em um evento significa adicionar manipuladores de eventos a um evento. Os manipuladores de eventos devem ter o mesmo tipo de retorno e assinatura que o delegado do evento.

Para adicionar um manipulador de eventos a um evento, você usa o +=operador. O manipulador de eventos pode ser um método de instância, um método estático , um método anônimo ou uma expressão lambda.

O seguinte mostra como assinar OnCreatedo evento:

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

        order.OnCreated += Email.Send;
        order.OnCreated += SMS.Send;

        order.Create();
    }
}Linguagem de código:  C#  ( cs )

Saída:

Order created
Send an email
Send an SMSLinguagem de código:  C#  ( cs )

Como funciona.

Primeiro, crie um novo Orderobjeto:

var order = new Order();Linguagem de código:  C#  ( cs )

Segundo, adicione manipuladores de eventos ao OnCreatedevento:

order.OnCreated += Email.Send;
order.OnCreated += SMS.Send;Linguagem de código:  C#  ( cs )

Terceiro, chame o Create()método do Orderobjeto:

order.Create();Linguagem de código:  C#  ( cs )

O Create()método gera o OnCreatedevento. Como as classes Emaile SMSestão inscritas no OnCreatedevento, os Send()métodos dessas classes são chamados automaticamente.

Junte tudo:

delegate void OrderEventHandler();

class Order
{
    public event OrderEventHandler OnCreated;

    public void Create()
    {
        Console.WriteLine("Order created");
        
        if(OnCreated != null)
        {
            OnCreated();
        }
    }
}


class Email 
{
    public static void Send()
    {
        Console.WriteLine($"Send an email");
    }
}

class SMS
{
    public static void Send()
    {
        Console.WriteLine($"Send an SMS");
    }
}

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

        order.OnCreated += Email.Send;
        order.OnCreated += SMS.Send;

        order.Create();
    }
}Linguagem de código:  C#  ( cs )

Manipulador de eventos

C# fornece o EventHandlertipo de delegado padrão para que você não precise definir um novo tipo de delegado ao usar eventos.

O seguinte mostra a declaração do EventHandlertipo delegado:

public delegate void EventHandler(object sender, EventArgs e);Linguagem de código:  C#  ( cs )

Neste tipo de delegado:

  • O sendercontém uma referência ao objeto que gerou o evento.
  • O EventArgsobjeto contém as informações de estado que podem ser aplicáveis ​​​​ao aplicativo.

É importante entender que o EventArgsfoi projetado para manipuladores de eventos que não precisam passar dados do editor para os assinantes. Se quiser passar os dados, você precisa definir uma classe derivada da EventArgsclasse.

O programa a seguir mostra como usar o EventHandlerevento de pedido criado:

class Order
{
    public event EventHandler OnCreated;

    public void Create()
    {
        Console.WriteLine("Order created");
        
        if(OnCreated != null)
        {
            OnCreated(this, EventArgs.Empty);
        }
    }
}


class Email 
{
    public static void Send(object sender, EventArgs e)
    {
        Console.WriteLine($"Send an email");
    }
}

class SMS
{
    public static void Send(object sender, EventArgs e)
    {
        Console.WriteLine($"Send an SMS");
    }
}


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

        order.OnCreated += Email.Send;
        order.OnCreated += SMS.Send;

        order.Create();
    }
}Linguagem de código:  C#  ( cs )

Como funciona.

Primeiro, use o EventHandlerem vez do OrderEventHandlertipo delegado:

public event EventHandler OnCreated;Linguagem de código:  C#  ( cs )

Segundo, aumente o OnCreatedevento passando o Orderobjeto (this) e EventArgs.Empty:

OnCreated(this, EventArgs.Empty);Linguagem de código:  C#  ( cs )

Observe que EventArgs.Emptyfornece um valor para usar com um evento que não possui dados de evento.

Terceiro, modifique a assinatura do Send()método das classes Emaile SMSpara corresponder ao EventHandlertipo de delegado:

public static void Send(object sender, EventArgs e)Linguagem de código:  C#  ( cs )

Passando dados estendendo EventArgs

Para passar dados no segundo parâmetro do manipulador de eventos do editor para os assinantes, você precisa definir uma classe que herde da EventArgsclasse e armazenar os dados que deseja passar na classe.

O programa a seguir ilustra como passar dados (e-mail e telefone) do editor ( Orderclasse) para os assinantes (classes de e-mail e SMS).

class OrderEventArgs : EventArgs
{
    public string Email { get; set; }
    public string Phone { get; set; }
}

class Order
{
    public event EventHandler<OrderEventArgs> OnCreated;

    public void Create(string email, string phone)
    {
        Console.WriteLine("Order created");

        if(OnCreated != null)
        {
            OnCreated(this, new OrderEventArgs { Email = email, Phone = phone });
        }
    }
}

class Email 
{
    public static void Send(object sender, OrderEventArgs e)
    {
        Console.WriteLine($"Send an email to {e.Email}");
    }
}

class SMS
{
    public static void Send(object sender, OrderEventArgs e)
    {
        Console.WriteLine($"Send an SMS to {e.Phone}");
    }
}

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

        order.OnCreated += Email.Send;
        order.OnCreated += SMS.Send;

        order.Create("[email protected]", "(408)-111-2222");
    }
}Linguagem de código:  C#  ( cs )

Saída:

Order id 1 created with the amount 100
Send an email to john@test.com
Send an SMS to (408)-111-2222Linguagem de código:  C#  ( cs )

Como funciona.

Primeiro, defina a OrderEventArgsclasse que herda da EventArgsclasse:

class OrderEventArgs : EventArgs
{
    public string Email { get; set; }
    public string Phone { get; set; }
}Linguagem de código:  C#  ( cs )

Segundo, defina o evento usando EventHanldero OrderEventArgstipo:

public event EventHandler<OrderEventArgs> OnCreated;Linguagem de código:  C#  ( cs )

Terceiro, crie um evento e uma nova instância da OrderEventArgsclasse:

OnCreated(this, new OrderEventArgs { Email = email, Phone = phone });Linguagem de código:  C#  ( cs )

Nesta instrução, o OrderEventArgsobjeto contém os dados de email e telefone.

Quarto, altere a Send()assinatura do método para usar OrderEventArgs:

public static void Send(object sender, OrderEventArgs e)Linguagem de código:  C#  ( cs )

Dentro do Send()método, você pode acessar o e-mail e o número de telefone através do OrderEventArgsobjeto.

Resumo

  • Os eventos permitem que uma classe ou objeto notifique outras classes ou objetos quando algo ocorre.
  • Os eventos são usados ​​em um padrão editor/assinante no qual o editor gera um evento e os assinantes respondem ao evento.
  • Use EventHandlercomo tipo delegado para declarar um evento.
  • Estenda a EventArgsclasse para transmitir dados do editor aos assinantes.

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *