class Program
{
delegate void StringProcessor(string input);
class Person
{
string name;
public Person(string name) { this.name = name; }
public void Say(string message)
{
Console.WriteLine("{0} says: {1}", name, message);
}
}
class Background
{
public static void Note(string note)
{
Console.WriteLine("({0})", note);
}
}
static void Main(string[] args)
{
Person jon = new Person("Jon");
Person tom = new Person("Tom");
StringProcessor jonsVoice, tomsVoice, background;
jonsVoice = new StringProcessor(jon.Say);
tomsVoice = new StringProcessor(tom.Say);
background = new StringProcessor(Background.Note);
StringProcessor p = new StringProcessor(jonsVoice);
p += tomsVoice;
p -= jonsVoice;
p("Hello");
}
}
此程序打印
Jon says: Hello
Tom says: Hello
而不是
Tom says: Hello
此删除不起作用:p -= jonsVoice;
但为什么?
您能否澄清一下这个问题,或者获取一些有关委托实例化的有用链接与另一位代表。我对卧底信息感兴趣。
答案 0 :(得分:0)
使用+ =运算符组合委托时,结果为Multicast Delegate,表示要调用的委托列表。 (事实上,所有代表都是多播代理,创建一个这样的代理:
jonsVoice = new StringProcessor(jon.Say);
导致多播委托在其InvocationList中具有单个委托。)
您可以使用 - =运算符从Invocation列表中删除委托。
那么为什么上面的例子不起作用?因为在p。
的调用列表中没有与jonsVoice匹配的委托p有一个由两个委托组成的调用列表:
这是因为你通过将StringProcessor构造函数传递给另一个StringProcessor来初始化p:
jonsVoice = new StringProcessor(jon.Say);
...
StringProcessor p = new StringProcessor(jonsVoice);
导致指向另一个StringProcessor委托的StringProcessor委托。
您可以通过调用该委托上的GetInvocationList方法来检查委托的调用列表。这将按照调用它们的顺序返回一组委托。
StringProcessor p = new StringProcessor(jonsVoice);
p += tomsVoice;
p -= jonsVoice;
foreach (var delegateItem in p.GetInvocationList())
{
Console.WriteLine("Delegate of {0}.{1}", delegateItem.Target.GetType().Name, delegateItem.Method.Name);
}
结果是:
Delegate of StringProcessor.Invoke
Delegate of Person.Say
当你调用p - = jonsVoice时,调用列表不包含指向jon对象的Person.Say方法的委托(就像jonsVoice那样),所以没有什么可以删除。
如果你这样初始化p: StringProcessor p = jonsVoice;
你应该得到你期望的结果。