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 Order
com 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
Order
classe é a editora. - As classes
Email
eSMS
são os assinantes.
Quando um pedido for criado, o Order
objeto notificará as classes Email
e SMS
para enviar um e-mail e SMS.
Declarando um evento
O seguinte declara o OnCreated
evento 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 OnCreated
evento 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 OnCreated
o 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 SMS
Linguagem de código: C# ( cs )
Como funciona.
Primeiro, crie um novo Order
objeto:
var order = new Order();
Linguagem de código: C# ( cs )
Segundo, adicione manipuladores de eventos ao OnCreated
evento:
order.OnCreated += Email.Send;
order.OnCreated += SMS.Send;
Linguagem de código: C# ( cs )
Terceiro, chame o Create()
método do Order
objeto:
order.Create();
Linguagem de código: C# ( cs )
O Create()
método gera o OnCreated
evento. Como as classes Email
e SMS
estão inscritas no OnCreated
evento, 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 EventHandler
tipo 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 EventHandler
tipo delegado:
public delegate void EventHandler(object sender, EventArgs e);
Linguagem de código: C# ( cs )
Neste tipo de delegado:
- O
sender
contém uma referência ao objeto que gerou o evento. - O
EventArgs
objeto contém as informações de estado que podem ser aplicáveis ao aplicativo.
É importante entender que o EventArgs
foi 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 EventArgs
classe.
O programa a seguir mostra como usar o EventHandler
evento 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 EventHandler
em vez do OrderEventHandler
tipo delegado:
public event EventHandler OnCreated;
Linguagem de código: C# ( cs )
Segundo, aumente o OnCreated
evento passando o Order
objeto (this) e EventArgs.Empty
:
OnCreated(this, EventArgs.Empty);
Linguagem de código: C# ( cs )
Observe que EventArgs.Empty
fornece um valor para usar com um evento que não possui dados de evento.
Terceiro, modifique a assinatura do Send()
método das classes Email
e SMS
para corresponder ao EventHandler
tipo 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 EventArgs
classe e armazenar os dados que deseja passar na classe.
O programa a seguir ilustra como passar dados (e-mail e telefone) do editor ( Order
classe) 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-2222
Linguagem de código: C# ( cs )
Como funciona.
Primeiro, defina a OrderEventArgs
classe que herda da EventArgs
classe:
class OrderEventArgs : EventArgs
{
public string Email { get; set; }
public string Phone { get; set; }
}
Linguagem de código: C# ( cs )
Segundo, defina o evento usando EventHanlder
o OrderEventArgs
tipo:
public event EventHandler<OrderEventArgs> OnCreated;
Linguagem de código: C# ( cs )
Terceiro, crie um evento e uma nova instância da OrderEventArgs
classe:
OnCreated(this, new OrderEventArgs { Email = email, Phone = phone });
Linguagem de código: C# ( cs )
Nesta instrução, o OrderEventArgs
objeto 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 OrderEventArgs
objeto.
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
EventHandler
como tipo delegado para declarar um evento. - Estenda a
EventArgs
classe para transmitir dados do editor aos assinantes.