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.