2012-10-18 69 views
1
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"); 

    } 
} 

这个程序打印C#委托实例化

Jon says: Hello 
Tom says: Hello 

,而不是

Tom says: Hello 

这去除不起作用:p -= jonsVoice;

但是,为什么?

能否请您澄清这个或获取有关与其他委托代理实例化一些有用的链接。我对卧底信息感兴趣。

回答

0

A delegate is an object which represents a method and, optionally, the "this" object associated with that method.

当你把使用+ =运营商的代表,结果是Multicast Delegate代表委托列表被调用。 (实际上所有代表都多路广播委托,创建委托这样的:

jonsVoice = new StringProcessor(jon.Say); 

导致多播委托与一个代表,在它的InvocationList)。 =运营商 -

您可以通过删除调用列表代表。

那么,为什么没有上述工作的例子吗?因为在p的调用列表中没有与jonsVoice匹配的委托。

p具有由两个代表的调用列表:

  • 一个指向在tomObject
  • 一个指向的一个StringProcessor对象

的Invoke方法的说法即是因为你通过将StringProcessor构造另一个StringProcessor初始化号码:

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); 
} 

导致:当你打电话p

Delegate of StringProcessor.Invoke 
Delegate of Person.Say 

- = jonsVoice,调用列表中不包含指向在乔恩的Person.Say方法对象(如jonsVoice做了委托),所以没有什么可以删除的。

如果初始化p喜欢这个: StringProcessor P = jonsVoice;

你应该得到你期望的结果。

+0

谢谢。现在这是可以理解的 – Realeyes