csharp-multidelegados

Qué es y cómo usar un multidelegado en C#

Un multidelegado es una instancia de un delegado que puede apuntar a más de un método. Cuando se invoca un multidelegado, todos los métodos apuntados por el delegado se ejecutan en orden.

Esta capacidad permite ejecutar múltiples métodos en respuesta a un solo evento o acción.

En realidad, en C# todos los delegados son multidelegados. Simplemente tenemos que usarlos de forma ligeramente distinta.

Sintaxis de multidelegados

Los multidelegados se crean combinando instancias de delegados utilizando el operador + o el método Delegate.Combine.

DelegatoTipo multidelegado = MiDelegado1 + MiDelegado2;

Aunque, en general, lo normal es que empleemos += para combinar los delegados “in-situ”.

Ejemplo básico

Lo vemos mejor con un ejemplo. Supongamos que tenemos dos métodos, Metodo1 y Metodo2, que ambos reciben un string. Por otro lado, tenemos una definición de MiDelegado que coincide con la firma de estos métodos.

Podemos crear una instancia de MiDelegado llamada mulidelegado que ejecute ambos métodos, creando dos delegados y combinándolos con +.

static void Metodo1(string mensaje)
{
    Console.WriteLine("Metodo1: " + mensaje);
}

static void Metodo2(string mensaje)
{
    Console.WriteLine("Metodo1: " + mensaje);
}

delegate void MiDelegado(string mensaje);

MiDelegado delegado1 = new MiDelegado(Metodo1);
MiDelegado delegado2 = new MiDelegado(Metodo2);

MiDelegado multidelegado = delegado1 + delegado2;
multidelegado("Hola Mundo");

// Output:
// Metodo1: Hola Mundo
// Metodo2: Hola Mundo

Sin embargo, como ya he dicho, lo es que empleemos += para combinarlos directamente. Esto se haría así:

MiDelegado multidelegado = Metodo1;
multidelegado += Metodo2;

Es equivalente a la creación del mutidelegado anterior, sin necesidad de crear delegado1 y delegado2. Es la sintaxis que usaréis habitualmente, pero está bien ver como funciona “bajo el capo”.

Desvincular un método

También es posible desvincular un método que hayamos incluido en un multidelegado. Para ello podemos usar el operador - o el método Delegate.Remove.

MiDelegado multidelegado2 = multidelegado - delegado1;

Para ello, de forma similar al caso de combinación de delegado, lo normal es que empleemos directamente el operador -=,

Lo vemos más fácil con un ejemplo. En el caso anterior,

// esto es lo que teníamos
MiDelegado multidelegado = Metodo1;
multidelegado += Metodo2;

// ahora quito Metodo1 del delegado
multidelegado -= Metodo1;

multidelegado("Hola mundo");

// Output:
// Metodo2: Hola Mundo

En este caso llamaría únicamente al Metodo2, porque hemos quitado Metodo1 del delegado.

Esta es una práctica muy común cuando veamos eventos, porque en ocasiones querremos dejar de escucharlos temporal o definitivamente.