Простой Делегат (делегат) по сравнению с Многоадресными делегатами

Я прошел много статей, но я все еще не соглашаюсь с различием между нормальными делегатами, которых мы обычно создаем и многоадресные делегаты.

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

Вышеупомянутый делегат MyMethodHandler назовет эти два метода. Теперь, где многоадресные делегаты входят. Я считал, что они могут назвать несколько методов, но я боюсь, что мое основное понимание о делегатах не корректно.

62
задан 23 November 2013 в 08:33

4 ответа

Многоадресный делегат является делегатом, который имеет ссылки больше чем на одну функцию. Когда Вы вызываете многоадресного делегата, все функции, на которые указывает делегат, вызываются.

Тип 1:

0 аргументов и пусто возвращают делегата типа -

Метод 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");
    }
}

Метод 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");
    }
}

Тип 2:

0 аргументов и интервал возвращают делегата типа

Метод 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;
    }
}

Метод 2-

Тот же процесс как Тип 1

Поэтому, когда существует тип возврата Многоадресного делегата, возвращаемое значение является возвращаемым значением последнего делегата.

Тип 3:

интервал, интервал, касательно международных аргументов и пусто возвращают делегата типа -

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
*/
-2
ответ дан 31 October 2019 в 13:39

Разъясниться немного: Весь делегаты являются экземплярами класса MulticastDelegate, независимо от того, есть ли у них один или несколько целевых методов. В принципе нет никакого различия между делегатом с синглом или несколькими целями, хотя время выполнения оптимизировано немного к общему падежу с единой целью. (Делегат с 0 целями не возможен, хотя, это - один или несколько.)

при инстанцировании делегата как new MyMethodHandler(Method1) Вы создаете делегата с единой целью (Method1 метод).

Делегаты с несколькими целями создаются путем объединения двух существующих делегатов. У получающегося делегата будет сумма целей. Делегаты могут быть объединены явно с Delegate.Combine(), но также и неявно при помощи += оператор на существующем делегате, как в Вашем примере.

Вызов делегата в свою очередь называет каждую цель в делегате. Таким образом в Вашем примере handler(someObject); назовет два метода (Method1 и Method2), так как Вы создали делегата с этими двумя целями.

5
ответ дан 31 October 2019 в 13:39

Извините за добавление к чьему-либо ответу, но я думал, что делегатов звонят в порядке, они добавляются.

раздел "Multicast Delegates"

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

4
ответ дан 31 October 2019 в 13:39

"Все экземпляры делегата многоадресно передали возможность". - http://msdn.microsoft.com/en-us/library/orm-9780596527570-03-04.aspx

"В C#, все типы делегата поддерживают многоадресную передачу" - http://msdn.microsoft.com/en-us/library/orm-9780596516109-03-09.aspx

11
ответ дан 31 October 2019 в 13:39

Другие вопросы по тегам:

Похожие вопросы: