Este artigo tem como objectivo esclarecer o que é um delegate e um evento, bem como exemplificar a implementação e a sua utilização numa aplicação.
Delegates
Um delegate é um tipo de referência utilizado para encapsular um método com uma determinada assinatura.
Exemplo:
public delegate string DevolveStringDelegate();
Esta declaração de um delegate pode encapsular qualquer método que não tenha parâmetros de entrada e devolva um objecto do tipo String.
Em exemplo de utilização de delegates
using System;
using System.Collections.Generic;
using System.Text;
namespace Delegates
{
public class Program
{
//Declaração de um delegate que tem como assinatura
//uma variável do tipo String
delegate void testeDelegate(string s);
static void Main(string[] args)
{
//texto que vai ser escrito na consola
string texto= "estou a ver um delegate a funcionar!";
//Cria-se uma instância do delegate e no construtor passa-se
//como parâmetro o nome do método que se quer utilizar, neste
//caso o método é o metodoComAssinaturaString porque contém
//a mesma assinatura que o delegate, tem como parâmetro
//uma variável do tipo String e devolve void
testeDelegate t = new testeDelegate(metodoComAssinaturaString);
//invocação do método que o delegate está a referênciar
//caso esse método tenha parâmetros, estes são inseridos
//ao utilizar o método invoke do delegate
t.Invoke(texto);
}
public static void metodoComAssinaturaString(string texto)
{
Console.WriteLine(texto);
}
}
}
E ao executar o programa…

Eventos
Agora que está esclarecido o que é um delegate e como se implementa, vamos utilizar esse conceito e avançar para a implementação de um evento.
Um evento é uma acção que é despoletada quando uma condição que está estabelecida se torna verdadeira.

Seguindo o diagrama acima apresentado, vou dar um exemplo de um evento. Temos um calendário, como o google calendar (quem publica os eventos) por exemplo, que permite a inserção de uma reunião, depois configuramos o google calendar para nos enviar um e-mail a avisar da reunião (subscrever o evento), no entanto podemos não ter acesso ao e-mail na hora que está marcada a reunião, assim, configuramos o google calendar para nos enviar uma SMS para além do e-mail (subscrever o evento).
Assim, quando chega a hora da reunião recebemos o aviso por dois canais diferentes, email e SMS, e que contém a mesma informação (EventArgs) no entanto a fonte da informação é a mesma, o google calendar!
Vamos então demonstrar um exemplo prático
using System;
using System.Collections.Generic;
using System.Text;
namespace DelegatesAndEvents
{
//classe que descreve a informação a ser publicada
public class ProcessarInformacaoEventArgs : EventArgs
{
private int _progresso;
public int progresso
{
get { return _progresso; }
set { _progresso = value; }
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace DelegatesAndEvents
{
//declaração do delegate que tem como parametro a
//classe ProcessarInformacaoEventArgs
//que é onde vai ser guardada a informação que é
//enviada quando é disparado o evento
public delegate void TickHandler(object sender,
ProcessarInformacaoEventArgs p);
//classe que publica o evento
public class ProcessarInformacao
{
//declaração do evento que utiliza o
//delegate TickHandler
public event TickHandler tick;
//Este método serve apenas de exemplo
//de processamento de informação
public void ProcessarInfo()
{
long time = 100000000000;
TimeSpan t = new TimeSpan(time);
while (t.Ticks > 0)
{
t = t.Subtract(new TimeSpan(1000));
long aux = time - t.Ticks;
long res = (aux * 100) / time;
//sempre que executa um ciclo, vai
//ser disparado um evento
//que vai ser recebido por todas as
//classes que o subscreveram
//e envia a informação processada
//por cada ciclo da estrutura
//de decisão while
OnTick((int)res);
}
}
protected void OnTick(int p)
{
//chama o construtor com parametros da
//classe ProcessarInformacaoEventArgs
//e invoca o evento com a informação que foi recebida
ProcessarInformacaoEventArgs args = new ProcessarInformacaoEventArgs(p);
tick(this,args);
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace DelegatesAndEvents
{
//programa que subscreve o evento da classe ProcessarInformacao
public class Program
{
static void Main(string[] args)
{
ProcessarInformacao p = new ProcessarInformacao();
//Subscreve o evento
p.tick += new TickHandler(p_tick);
//Executar o processo que vai disparar o evento
p.ProcessarInfo();
Console.Read();
}
//Aqui é processada a informação enviada quando o evento é disparado
static void p_tick(ProcessarInformacaoEventArgs p)
{
Console.WriteLine(p.progresso);
Console.Clear();
}
}
}
Resultado da aplicação – Apresenta a percentagem de informação já processada.
Pode descarregar todos os projectos de este post aqui.
Demos desenvolvidas em VS2005.