C# - Combinando Delegates (Delegate.Combine)
Hoje veremos como podemos combinar Delegates na linguagem C#. |
Vamos começar lembrando a definição de delegate:
"Um delegate é um elemento da linguagem C# que permite que você faça referência a um método."
Assim, usando um delegate você pode encapsular a referência a um método dentro de um objeto de delegação.
O objeto de delegação pode ser passado para o código o qual pode chamar o método referenciado sem ter que saber em tempo de compilação qual método será chamado.
Uma das formas simples de ver isso funcionando são os eventos. Para simplificar vou usar os eventos dos controles Windows Forms.
Em projeto Windows Forms quando temos um formulário com controles como o TextBox geralmente usamos os eventos desses controles para realizar alguma ação.
Assim vamos supor que temos um formulário Form1.cs com dois botões de comando : btnCancelar e btnOK.
A forma mais simples de usar os eventos neste caso e apenas clicar nos botões e acessar o código para o evento que é gerado automaticamente:
private void btnOK_Click(object sender, EventArgs e) { } private void btnCancelar_Click(object sender, EventArgs e)
{
}
|
Uma outra forma é definir os eventos via código em um método no formulário.
Para isso, vamos definir uma chamada para um método EventosControles() no construtor do formulário, e, a seguir criar este método.
Neste método vamos acessar o evento Click dos controles Buttons, definir um evento do tipo EventHandler, e, criar um método que manipula esse evento:
Pressionando F12 sobre o evento Click veremos a
assinatura: public event EventHandler Click; vamos então atribuir o evento EventHandler ao atributo Click e como argumento vamos definir o método btnOK_Click para o botão btnOK e repetindo o processo para o botão btnCancelar vamos definir o método btnCancelar_Click |
Teremos assim o seguinte código no formulário:
using System;
using System.Windows.Forms;
namespace Combinando_Delegates
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
EventosControles();
}
private void EventosControles()
{
this.btnOK.Click += new EventHandler(this.btnOK_Click);
this.btnCancelar.Click += new EventHandler(this.btnCancelar_Click);
}
private void btnCancelar_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
Close();
}
private void btnOK_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Ok;
Close();
}
}
}
|
Para criar os métodos btnCancelar_Click e btnOK_Click pressionamos F12 no evento EventHandler e verificamos que a assinatura deste evento é:
Assim os métodos criados tem que retornar void e possuir dois parâmetros : object e EventArgs para se adequar à assinatura do delegate. Observe que usamos o operador += para incluir um comportamento quando o evento ocorrer.
Dessa forma o argumento do construtor do delegate fortemente tipado é uma referência para um método que respeita sua assinatura.
Agora note que temos código duplicado pois ambos os métodos chamam o método Close();
Vamos então simplificar o código definindo um novo método Fechar() onde chamamos o método Close(); e passando este método como um argumento para o delegate EventHandler,
using System;
using System.Windows.Forms;
namespace Combinando_Delegates
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
EventosControles();
}
private void EventosControles()
{
this.btnOK.Click += new EventHandler(this.btnOK_Click);
this.btnCancelar.Click += new EventHandler(this.btnCancelar_Click);
//
btnOK.Click += new EventHandler(Fechar);
btnCancelar.Click += new EventHandler(Fechar);
}
private void btnCancelar_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
}
private void btnOK_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.OK;
}
private void Fechar (object sender, EventArgs e)
{
Close();
}
}
}
|
Melhorou mas podemos ir além...
Podemos otimizar o código combinando os delegates e podemos fazer isso usando duas sintaxes distintas:
O primeiro usa a sobrecarga do operador +, e, o segundo, o método Delegate.Combine que concatena listas de invocação de um matriz de delegates.
Assim o nosso código, já otimizado, ficaria assim:
using System;
using System.Windows.Forms;
namespace Combinando_Delegates
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
EventosControles();
}
private void EventosControles()
{
var OkEventHandler = (EventHandler)btnOK_Click + Fechar;
var cancelarEventHandler = (EventHandler)Delegate.Combine((EventHandler)btnCancelar_Click, (EventHandler)Fechar);
//
btnOK.Click += OkEventHandler;
btnCancelar.Click += cancelarEventHandler;
}
private void btnCancelar_Click(object sender, EventArgs e)=> DialogResult = DialogResult.Cancel;
private void btnOK_Click(object sender, EventArgs e) => DialogResult = DialogResult.OK;
private void Fechar (object sender, EventArgs e) => Close();
}
}
|
Embora o exemplo seja bem simples deu para perceber que usando o recurso dos delegates podemos combinar invocações de mais de um delegate e tornar o nosso código mais elegante.
E estamos conversados...
"Disse-lhes, pois,
Jesus: Quando levantardes o Filho do homem, então conhecereis que EU SOU, e que
nada faço por mim mesmo; mas isto falo como meu Pai me ensinou."
João 8:28
Veja os
Destaques e novidades do SUPER DVD Visual Basic
(sempre atualizado) : clique e confira !
Quer migrar para o VB .NET ?
Quer aprender C# ??
Quer aprender os conceitos da Programação Orientada a objetos ? Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ? |
Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#
Super DVD C# - Recursos de aprendizagens e vídeo aulas para C#
Curso Fundamentos da Programação Orientada a Objetos com VB .NET
C# - Usando delegates para chamar operações matemáticas - Macoratti