简单委托(委托)与多播委托

我看过许多文章,但是我仍然不清楚我们通常创建的普通委托和多播委托之间的区别。

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

上面的委托 MyMethodHandler 将调用这两个方法。 现在,多播委托从何而来。我读到过他们可以调用多个方法,但是恐怕我对委托的基本理解是不正确的。

61308 次浏览

代表们进来了。NET 是多播委托。无论您选择为它们附加零个、一个还是多个处理程序,它们仍然是多播委托。

这篇文章 很好地解释了这一点:

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.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

对不起,我添加了别人的答案,但我认为代表是按照他们被添加的顺序被调用的。

“多播代表”部分

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

说明一下: 全部委托是类 MulticastDelegate的实例,不管它们有一个还是多个目标方法。原则上,具有单个目标或多个目标的委托之间没有区别,尽管运行时针对具有单个目标的公共情况进行了一些优化。(0目标的委托是不可能的,它是一个或多个目标。)

在实例化诸如 new MyMethodHandler(Method1)之类的委托时,可以使用单个目标(Method1方法)创建委托。

具有多个目标的委托是通过组合两个现有委托创建的。生成的委托将具有目标的和。委托可以与 Delegate.Combine()显式组合,但也可以通过在现有委托上使用 +=操作符隐式组合,如您的示例所示。

依次调用委托调用委托中的每个目标。因此,在您的示例中,handler(someObject);将调用两个方法(Method1Method2) ,因为您已经用这两个目标创建了一个委托。

多路广播委托是对多个函数具有引用的委托。调用多播委托时,将调用该委托所指向的所有函数。

第一类:

0参数和 void 返回类型的委托-

方法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");
}
}

第二类:

0参数和 int 返回类型委托

方法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 委托的返回类型时,返回值是最后一个委托的返回值。

第三类:

Int、 int、 ref int 参数和 void 返回类型 committee-

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