Delegados con métodos con nombre y Métodos anónimos (Guía de programación de C#)
Un delegado puede asociarse con un método con nombre. Cuando crea una instancia de un delegado mediante un método con nombre, el método se pasa como un parámetro, por ejemplo:
// 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;
Esto se llama con un método con nombre. Los delegados construidos con un método con nombre pueden encapsular un método estático o un método de instancia. Los métodos con nombre son la única manera de crear una instancia de un delegado en versiones anteriores de C#. En cambio, en una situación en la que crear un método nuevo es una sobrecarga no deseada, C# le permite crear una instancia de un delegado y especificar inmediatamente un bloque de código que el delegado procesará cuando se llame. El bloque puede contener una expresión lambda o un método anónimo.
El método que pasa como un parámetro de delegado debe tener la misma firma que la declaración de delegado. Una instancia de delegado puede encapsular un método de instancia o estático.
Nota
Aunque el delegado puede usar un parámetro out, no recomendamos su uso con delegados de eventos de multidifusión porque no puede conocer a qué delegado se llamará.
A partir de C# 10, los grupos de métodos con una única sobrecarga tienen un tipo natural. Esto significa que el compilador puede deducir el tipo de valor devuelto y los tipos de parámetro para el tipo delegado:
var read = Console.Read; // Just one overload; Func<int> inferred
var write = Console.Write; // ERROR: Multiple overloads, can't choose
Ejemplos
A continuación se muestra un ejemplo sencillo de cómo declarar y usar un delegado. Tenga en cuenta que tanto el delegado, MultiplyCallback
, como el método asociado, MultiplyNumbers
, tienen la misma firma
// 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
*/
En el ejemplo siguiente, un delegado se asigna a métodos estáticos y de instancia y devuelve información específica de cada uno.
// 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.
*/