csharp-delegados

Qué son y cómo usar los delegados en C#

Un delegado es un tipo que representa una referencia a una función o método. Los delegados permiten que los métodos se pasen como parámetros, se asignen a variables y se ejecuten dinámicamente en tiempo de ejecución.

Para ello, el delegado debe coincidir con la firma (parámetros recibidos) por la función, y con su retorno específico.

En términos simples, un delegado puede considerarse como una especie de puntero a función, pero con la seguridad y la robustez del sistema de tipos de C#.

Declaración de un delegado

Para declarar un delegado en C# se utiliza la palabra clave delegate, seguida de la firma del método que el delegado representará.

delegate TipoRetorno MiDelegado(Tipo parametro1...);
  • TipoRetorno, el tipo de retorno de la función que queremos delegar
  • Tipo parametro…, los parámetros de la función que queremos delegar

Por ejemplo, si queremos declarar un delegado que represente un método que no devuelve ningún valor y toma dos parámetros enteros, la declaración se vería así:

Ejemplo básico

Por ejemplo, si quisiéramos definir un delegado que pueda apuntar a cualquier función que tome un string como parámetro y no retorne ningún valor (void), podríamos hacerlo así:

public delegate void MiDelegado(string mensaje);

Y si queremos declarar un delegado que referencia una función que tome dos parámetros int y devuelva un double la declaración se vería así:

delegate void MiDelegado(int parametro1, int parametro2);

Uso de delegados

Asignación de un método a un delegado

Una vez declarado el delegado, podemos crear una instancia del delegado y asignarle un método que coincida con su firma.

Para ello podemos crearlo usando su constructor

MiDelegado delegado = new MiDelegado(FuncionReferenciada);

O simplemente asignarlo

MiDelegado delegado = FuncionReferenciada;

Veámoslo con un ejemplo. Supongamos que tenemos la función MostrarMensaje(string ...).

// Método que queremos referenciar
public static void MostrarMensaje(string mensaje)
{
	Console.WriteLine("Delegado:" + mensaje);
}

// Definición del delegado
public delegate void MiDelegado(string mensaje);

public static void Main(string[] args)
{
	// Ahora creamos un MiDelegado que apunte a MostrarMensaje
	MiDelegado delegado = MostrarMensaje;
}

Aquí hemos,

  • Definido un delegado MiDelegado, que coincide con la forma de MostrarMensaje.
  • Creado una nueva instancia de MiDelegado, llamada delegado
  • Asignado la instancia delegado a MostrarMensaje.

Invocando un delegado

Una vez que hemos creado definido el delegado, credo un delegado, y referenciada una función con él, podemos invocarlo simplemente haciendo () como haríamos con la función original.

En el ejemplo anterior, podríamos invocar delegado simplemente así.

// Invocación del método a través del delegado
delegado("Hola, Mundo!");
}

Por lo que se mostraría en pantalla

Delegado: Hola, Mundo!

Delegados genéricos: Func y Action

Para simplificar el uso de delegados, C# dispone de delegados genéricos predefinidos.

Los más comunes son Action y Func .

  • Action: Representa un método que no retorna un valor
  • Func<TResult>: Representa un método que retorna un valor de tipo TResult

Uso de Action

Action<string> mostrar = mensaje => Console.WriteLine(mensaje);

mostrar("Hola con Action!");

Uso de Func

Func<int, int, int> sumar = (a, b) => a + b;
int resultado = sumar(3, 4);

Console.WriteLine("Resultado de la suma: " + resultado);

En general, esta forma es la que usaréis normalmente, frente a definir el delegado explícitamente. Sobre todo si es un uso temporal, que no merece la pena definir de forma tradicional.

Delegados Multicast

Un delegado Multicast es un delegado que puede tener más de un método en su invocación. En realidad, todos los delegados de C# son Multicast

Uso de delegados con eventos

Los delegados son la base de los eventos en C#. Un evento es una notificación enviada por un objeto para señalar la ocurrencia de una acción. Los delegados permiten suscribir métodos que serán llamados cuando se dispara el evento.

Ejemplos prácticos