Desenvolvimento - C#

Delegates e Eventos com C#.NET

Este artigo explica alguns principios básicos para um bom entendimento e utilização de Delegates e Eventos no .NET Framework utilizando-se a linguagem C#.

por Cristian Fernandes



Este artigo explica alguns principios básicos e introdutórios para um bom entendimento e utilização de Delegates e Eventos no .NET Framework utilizando-se a linguagem C#.

Delegates em C#.NET

Quando desenvolvemos em C++ temos um recurso bem interessante que é a “Callback Function”, que nada mais é do que a prática de passar um ponteiro de uma função como parâmetro para outra função.

Delegate é algo similar, entretanto é mais seguro de ser utilizado comparando-se com os ponteiros para funções em C++.Um delegate pode ser utilizado como referência para uma ou mais funções em C# e ser invocado quando necessário.

Um delegate ao ser criado precisa de um nome e da declaração dos parâmetros necessários, sejam de entrada ou de saída, um delegate não é uma construção simples como um “enum” ou algo do tipo, mas sim uma Classe.Qualquer delegate ao ser declarado é herdado da classe base delegate, que faz parte da biblioteca de classes do .NET.

Na verdade um delegate pode ser herdado de duas classes distintas System.Delegate ou System.MulticastDelegate, se o delegate tiver um tipo de retorno “void” ele é automaticamente um System.MulticastDelegate, assim ele suporta inúmeras funções com um operador “+=”.

Se o delegate tiver um tipo de retorno não “void” ele é um System.Delegate e não suporta multiplos métodos como o caso anterior.

Vamos dar uma olhada no seguinte exemplo de código:

class Figura

{

public Figura(float a, float b, float c)

{

m_xPos = a;

m_yPos = b;

m_zPos = c;

}

public void InverterX()

{

m_xPos = - m_xPos;

}

public void InverterY()

{

m_yPos = - m_yPos;

}

public void InverterZ()

{

m_zPos = - m_zPos;

}

private float m_xPos = 0;

private float m_yPos = 0;

private float m_zPos = 0;

}

Agora temos uma classe chamada Figura que possui três atributos privados que são usados para armazenar sua posição e três métodos para inverter sua posição por cada eixo.Agora iremos declarar o seguinte delegate:

public delegate void FiguraDelegate();

Agora na função main iremos declarar o seguinte:

Figura Minhafigura = new Figura(10,20,30);

FiguraDelegate fx = new FiguraDelegate(Minhafigura.InverterX);

FiguraDelegate fy = new FiguraDelegate(Minhafigura.InverterY);

FiguraDelegate fz = new FiguraDelegate(Minhafigura.InverterZ);

MulticastDelegate f_del = fx+fy+fz;

Neste exemplo nós criamos três delegates do tipo FiguraDelegate, um para cada método da nossa classe figura agora cada delegate mantém o endereço de um método da nossa classe.A última linha de código é muito interessante, nela criamos um delegate do tipo da classe base (MulticastDelegate) e adicionamos a ele os nossos três delegates criados anteriormente.

Como todos os nossos métodos são “void”, eles automaticamente são do tipo MulticastDelegate, sendo assim podem suportar multiplas invocações de métodos.

Então podemos perfeitamente codificar desta maneira e utilizar o delegate para mais de um método:

Figure Minhafigura = new Figura(10,20,30);

FiguraDelegate fMulti = new FiguraDelegate(figure.InverterX);

fMulti += new FiguraDelegate(figure.InverterY);

fMulti();

Eventos em C#.NET

A utilização de delegates não se aplica somente ao fato de que eles podem manter a referência das funções mas também ao fato de que pode definir e usar nomes de função em tempo de execução e não em tempo de compilação.

Uma grande vantagem da utilização de delegates é a sua aplicabilidade no modelo de eventos do .NET. Eventos são ações do sistema nas manipulações do usuário (Ex: Clique do Mouse, Tecla Pressionada, etc) ou qualquer evento disparado pelo programa, mesmo os gerados pelo programador.

Para entender a utilização de delegates no modelo de eventos do .NET os exemplos anteriores são usados aqui, vamos adicionar à nossa classe figura o seguinte:

public delegate void FiguraHandler(string msg);

public static event FiguraHandler Invertido;

public void InverterZ()

{

m_zPos = - m_zPos;

Invertido("invertida pelo eixo Z!");

}

Agora temos um delegate declarado e um evento que utiliza este delegate, em cada método nós devemos chamar o nosso evento o próximo exemplo demonstra isso claramente.

static void Main (string[] args)

{

Figure Minhafigura = new Figura(10,20,30);

Figure.Invertido += new Test.Figura.FiguraHandler(OnFiguraInvertida);

Minhafigura.InverterX();

Console.WriteLine(“\r\n”);

Minhafigura.InverterZ();

}

private static void OnFiguraInvertida(string msg)

{

Console.WriteLine("A figura foi {0}",msg);

}

Então, na função principal nós devemos criar um objeto apartir da classe Figura e ligar o manipulador de eventos (Event Handler) ao método OnFiguraInvertida. E quando nós chamamos algum dos métodos de inversão o evento é disparado e isso chama o nosso manipulador de eventos.

A aplicação irá imprimir a seguinte string no console:


A figura foi invertida pelo eixo X!

A figura foi invertida pelo eixo Z!

Estes foram alguns exemplos simples e introdutórios sobre como utilizar delegates e eventos no .NET Framework juntamente com a linguagem C#.

Espero ter contribuído,

Cristian Fernandes

Cristian Fernandes

Cristian Fernandes - Desenvolvedor de sistemas Web desde 2003 utilizando ASP e .NET, trabalha também com dispositivos móveis(Pocket PC e PALM) desde 2005 com C, C++ e C#.
Graduando em Ciência da Computação pela UNISINOS-RS.
Atualmente trabalha como desenvolvedor na empresa Pmweb de Porto Alegre.