Delegados com métodos nomeados vs. anônimos (Guia de Programação em C#)
Um delegado pode ser associado a um método nomeado. Quando você instancia um delegado usando um método nomeado, o método é passado como um parâmetro, por exemplo:
// Declare a delegate.
delegate void WorkCallback(int x);
// Define a named method.
void DoWork(int k) { /* ... */ }
// Instantiate the delegate using the method as a parameter.
WorkCallback d = obj.DoWork;
Isso é chamado usando um método nomeado. Os delegados construídos com um método nomeado podem encapsular um método estático ou um método de instância. Os métodos nomeados são a única maneira de instanciar um delegado em versões anteriores do C#. No entanto, em uma situação em que a criação de um novo método é uma sobrecarga indesejada, o C# permite que você instancie um delegado e especifique imediatamente um bloco de código que o delegado processará quando for chamado. O bloco pode conter uma expressão lambda ou um método anônimo.
O método que você passa como um parâmetro delegado deve ter a mesma assinatura que a declaração de delegado. Uma instância delegada pode encapsular o método estático ou de instância.
Nota
Embora o delegado possa usar um parâmetro out , não recomendamos seu uso com delegados de eventos multicast porque você não pode saber qual delegado será chamado.
Grupos de métodos com uma única sobrecarga têm um tipo natural. Isso significa que o compilador pode inferir o tipo de retorno e os tipos de parâmetro para o tipo delegado:
var read = Console.Read; // Just one overload; Func<int> inferred
var write = Console.Write; // ERROR: Multiple overloads, can't choose
Exemplos
A seguir está um exemplo simples de declarar e usar um delegado. Observe que tanto o delegado, MultiplyCallback
quanto o método associado, MultiplyNumbers
têm a mesma assinatura
// Declare a delegate
delegate void MultiplyCallback(int i, double j);
class MathClass
{
static void Main()
{
MathClass m = new MathClass();
// Delegate instantiation using "MultiplyNumbers"
MultiplyCallback d = m.MultiplyNumbers;
// Invoke the delegate object.
Console.WriteLine("Invoking the delegate using 'MultiplyNumbers':");
for (int i = 1; i <= 5; i++)
{
d(i, 2);
}
// Keep the console window open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
// Declare the associated method.
void MultiplyNumbers(int m, double n)
{
Console.Write(m * n + " ");
}
}
/* Output:
Invoking the delegate using 'MultiplyNumbers':
2 4 6 8 10
*/
No exemplo a seguir, um delegado é mapeado para métodos estáticos e de instância e retorna informações específicas de cada um.
// Declare a delegate
delegate void Callback();
class SampleClass
{
public void InstanceMethod()
{
Console.WriteLine("A message from the instance method.");
}
static public void StaticMethod()
{
Console.WriteLine("A message from the static method.");
}
}
class TestSampleClass
{
static void Main()
{
var sc = new SampleClass();
// Map the delegate to the instance method:
Callback d = sc.InstanceMethod;
d();
// Map to the static method:
d = SampleClass.StaticMethod;
d();
}
}
/* Output:
A message from the instance method.
A message from the static method.
*/