Programing

단순 대리자 (대리자) 대 멀티 캐스트 대리자

lottogame 2020. 11. 27. 07:39
반응형

단순 대리자 (대리자) 대 멀티 캐스트 대리자


나는 많은 기사를 읽었지만 우리가 일반적으로 만드는 일반 델리게이트와 멀티 캐스트 델리게이트의 차이점에 대해 아직 명확하지 않습니다.

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

위의 델리게이트 MyMethodHandler는이 두 메서드를 호출합니다. 이제 멀티 캐스트 델리게이트가 들어오는 곳입니다. 여러 메서드를 호출 할 수 있다는 것을 읽었지만 델리게이트에 대한 기본적인 이해가 올바르지 않을 것 같습니다.


이 기사에서는 이에 대해 잘 설명합니다.

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!
*/

C # 사양에는 모든 대리자 형식이 System.Delegate. 실제로 구현에서이를 구현하는 방식은 모든 대리자 유형이에서 System.MulticastDelegate파생되고 System.Delegate.

분명합니까? 귀하의 질문에 대한 답변이 확실하지 않습니다.


"모든 델리게이트 인스턴스에는 멀티 캐스트 기능이 있습니다." -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


좀 명확히하기 위해 : 모든 대리자는 MulticastDelegate대상 메서드가 하나 또는 여러 개 있는지 여부에 관계없이 클래스의 인스턴스입니다 . 원칙적으로 단일 또는 다중 대상이있는 대리자간에 차이가 없지만 런타임은 단일 대상이있는 일반적인 경우에 약간 최적화되어 있습니다. (대상이 0 인 델리게이트는 불가능하지만 하나 이상입니다.)

와 같은 대리자를 인스턴스화 할 때 new MyMethodHandler(Method1)단일 대상 ( Method1메서드)이 있는 대리자를 만듭니다 .

대상이 여러 개인 대리자는 두 개의 기존 대리자를 결합하여 생성됩니다. 결과 대리자는 대상의 합계를 갖게됩니다. 대리자는와 명시 적으로 결합 할 수 Delegate.Combine()있지만 +=예제와 같이 기존 대리자 에서 연산자를 사용하여 암시 적으로도 결합 할 수 있습니다 .

차례로 델리게이트를 호출하면 델리게이트의 모든 대상이 호출됩니다. 따라서이 두 대상을 사용하여 대리자를 만들었 으므로 예제에서는 handler(someObject);두 개의 메서드 ( Method1Method2)를 호출 합니다.


다른 사람의 답변에 추가해서 죄송하지만 델리게이트는 추가 된 순서대로 호출되는 것으로 생각했습니다.

"멀티 캐스트 대리자"섹션

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


멀티 캐스트 대리자는 둘 이상의 함수에 대한 참조가있는 대리자입니다. 멀티 캐스트 델리게이트를 호출하면 델리게이트가 가리키는 모든 함수가 호출됩니다.

유형 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과 동일한 프로세스

따라서 MultiCast Delegate의 반환 유형이있는 경우 반환 값은 마지막 대리자의 반환 값입니다.

유형 3 :

int, int, ref int 인수 및 void 반환 유형 대리자-

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
*/

참고 URL : https://stackoverflow.com/questions/2192219/simple-delegate-delegate-vs-multicast-delegates

반응형