Delegado simple (delegado) vs. delegates de multidifusión

He revisado muchos artículos, pero todavía no tengo clara la diferencia entre los delegates normales que generalmente creamos y los delegates de multidifusión.

public delegate void MyMethodHandler(object sender); MyMethodHandler handler = new MyMethodHandler(Method1); handler += Method2; handler(someObject); 

El delegado anterior MyMethodHandler llamará a estos dos métodos. Ahora, ¿dónde entran los delegates de multidifusión? He leído que pueden llamar a varios métodos, pero me temo que mi comprensión básica sobre los delegates no es correcta.

Este artículo lo explica bastante bien:

 delegate void Del(string s); class TestClass { static void Hello(string s) { System.Console.WriteLine(" Hello, {0}!", s); } static void Goodbye(string s) { System.Console.WriteLine(" Goodbye, {0}!", s); } static void Main() { Del a, b, c, d; // Create the delegate object a that references // the method Hello: a = Hello; // Create the delegate object b that references // the method Goodbye: b = Goodbye; // The two delegates, a and b, are composed to form c: c = a + b; // Remove a from the composed delegate, leaving d, // which calls only the method Goodbye: d = c - a; System.Console.WriteLine("Invoking delegate a:"); a("A"); System.Console.WriteLine("Invoking delegate b:"); b("B"); System.Console.WriteLine("Invoking delegate c:"); c("C"); System.Console.WriteLine("Invoking delegate d:"); d("D"); } } /* Output: Invoking delegate a: Hello, A! Invoking delegate b: Goodbye, B! Invoking delegate c: Hello, C! Goodbye, C! Invoking delegate d: Goodbye, D! */ 

La especificación C # establece que todos los tipos de delegado deben ser convertibles a System.Delegate . De hecho, la forma en que la implementación implementa esto es que todos los tipos de delegates se derivan de System.MulticastDelegate , que a su vez deriva de System.Delegate .

¿Está claro? No estoy seguro de que haya respondido tu pregunta.

“Todas las instancias delegadas tienen capacidad de multidifusión”. – http://msdn.microsoft.com/en-us/library/orm-9780596527570-03-04.aspx

“En C #, todos los tipos de delegates admiten multidifusión” – http://msdn.microsoft.com/en-us/library/orm-9780596516109-03-09.aspx

Perdón por agregar a la respuesta de otra persona, pero pensé que se llama a los delegates en el orden en que se agregan.

Sección “Delegados de multidifusión”

http://msdn.microsoft.com/en-us/library/orm-9780596527570-03-04.aspx

Para aclarar un poco: todos los delegates son instancias de la clase MulticastDelegate , independientemente de si tienen uno o varios métodos de destino. En principio, no hay diferencia entre un delegado con un objective único o múltiples, aunque el tiempo de ejecución se optimiza un poco hacia el caso común con un único objective. (Sin embargo, un delegado con 0 objectives no es posible, es uno o más).

Cuando crea una instancia de un delegado como new MyMethodHandler(Method1) , crea un delegado con un único objective (el método Method1 ).

Los delegates con objectives múltiples se crean al combinar dos delegates existentes. El delegado resultante tendrá la sum de objectives. Los delegates se pueden combinar de forma explícita con Delegate.Combine() , pero también implícitamente utilizando el operador += en un delegado existente, como en su ejemplo.

Invocar un delegado a su vez llama a todos los destinos del delegado. Entonces en tu handler(someObject); ejemplo handler(someObject); llamará a dos métodos ( Method1 y Method2 ), ya que ha creado un delegado con estos dos objectives.

Un delegado de multidifusión es un delegado que tiene referencias a más de una función. Cuando invoca a un delegado de multidifusión, se invocan todas las funciones a las que apunta el delegado.

Tipo 1:

0 argumento y delegado de tipo retorno de nulo –

Método 1 –

 using System; delegate void SampleDelegate (); //A delegate with 0 argument and void return type is declared class MainClass { public static void Main () { SampleDelegate Del1 = new SampleDelegate (Message1); //Del1 declared which points to function Message1 SampleDelegate Del2 = new SampleDelegate (Message2); //Del2 declared which points to function Message2 SampleDelegate Del3 = new SampleDelegate (Message3); //Del3 declared which points to function Message3 SampleDelegate Del4 = Del1 + Del2 + Del3; //Del4 declared which points to function Message4 //Del4 is then initialized as sum of Del1 + Del2 + Del3 Del4 (); //Del4 is invoked; //Del4 in turn invokes Del1, Del2 and Del3 in the same order they were initialized to Del4 //Del1, Del2, Del3 in turn invokes their respective functions to which they point to //The three functions Message1, Message2 and Message3 gets executed one after another } //Output: //This is message 1 //This is message 2 //This is message 3 Del4 - Del1; //Removes Del1 from Del4 Del4(); //New Output: //This is message 2 //This is message 3 Del4 + Del1; //Again adds Del1 to Del4 Del4(); //New Output: //This is message 1 //This is message 2 //This is message 3 public static void Message1 () //First sample function matching delegate signature { Console.WriteLine ("This is message 1"); } public static void Message2 () //Second sample function { Console.WriteLine ("This is message 2"); } public static void Message3 () //Third sample function { Console.WriteLine ("This is message 3"); } } 

Método 2

 using System; delegate void SampleDelegate (); class MainClass { public static void Main () { SampleDelegate del = new SampleDelegate (Message1); //Declares del and initializes it to point to method Message1 del += Message2; //Now method Message2 also gets added to del. Del is now pointing to two methods, Message1 and Message2. So it is now a MultiCast Delegate del += Message3; //Method Message3 now also gets added to del del (); //Del invokes Message1, Message2 and Message3 in the same order as they were added /* Output: This is Message1 This is Message2 This is Message3 */ del -= Message1; //Method Message1 is now removed from Del. It no longer points to Message1 //Del invokes the two remaining Methods Message1 and Message2 in the same order del (); /* New Output: This is Message2 This is Message3 */ del += Message4; //Method Message4 gets added to Del. The three Methods that Del oints to are in the order 1 -> Message2, 2 -> Message3, 3 -> Message4 //Del invokes the three methods in the same order in which they are present. del (); /* New Output: This is Message2 This is Message3 This is Message4 */ } public static void Message1 () { Console.WriteLine ("This is Message1"); } public static void Message2 () { Console.WriteLine ("This is Message2"); } public static void Message3 () { Console.WriteLine ("This is Message3"); } public static void Message4 () { Console.WriteLine ("This is Message4"); } } 

Tipo 2:

0 argumentos y delegado de tipo de retorno int

Método 1-

 using System; delegate int SampleDelagate (); class MainClass { public static void Main () { SampleDelagate del1 = new SampleDelagate (Method1); SampleDelagate del2 = new SampleDelagate (Method2); SampleDelagate del3 = new SampleDelagate (Method3); SampleDelagate del4 = del1 + del2 + del3; int ValueReturned = del4 (); //Del4 invokes Del1, Del2, Del3 in the same order. Here the return type is int. So the return of last delegate del3 is returned. Del3 points to Method3. So returned value is 3. Console.WriteLine (ValueReturned); //Output: 3 } public static int Method1 () { return 1; } public static int Method2 () { return 2; } public static int Method3 () { return 3; } } 

Método 2-

Mismo proceso que el Tipo 1

Entonces, cuando hay un tipo de devolución de un Delegado MultiCast, el valor de retorno es el valor de retorno del último delegado.

Tipo 3:

int, int, ref int arguments y void return type delegate –

 using System; delegate void SampleDelegate (ref int SampleReferenceParameter); class MainClass { public static void Main () { SampleDelegate del1, del2, del3, del4; del1 = new SampleDelegate (SampleMethodOne); del2 = new SampleDelegate (SampleMethodTwo); del3 = new SampleDelegate (SampleMethodTwo); del4 = del1 + del2 + del3 - del3; int SampleReferenceParameterValue = 0; del4 (ref SampleReferenceParameterValue); Console.WriteLine (SampleReferenceParameterValue); } public static void SampleMethodOne (ref int SampleReferenceParameter) { SampleReferenceParameter = 1; } public static void SampleMethodTwo (ref int SampleReferenceParameter) { SampleReferenceParameter = 2; } public static void SampleMethodThree (ref int SampleReferenceParameter) { SampleReferenceParameter = 3; } } /* Here del4 is first set as sum of del1, del2 and del3. Then del3 is subtracted from del4. So del4 now has del1, del2. When del4 is invoked, first del1 and then del2 is invoked. del1 sets reference parameter to 1. del2 sets reference parameter to 2. But since del2 is called last final value of reference parameter is 2 */