2012-10-18 2 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이다. (사실 모든 대표단은 다음과 같이 대리자를 생성, 멀티 캐스트 대표 있습니다 : 그것은 InvocationList을의 단일 대표와 멀티 캐스트 위임에

jonsVoice = new StringProcessor(jon.Say); 

결과).

- = 연산자를 사용하여 호출 목록에서 대리자를 제거 할 수 있습니다.

그렇다면 왜 위의 예가 효과가 없었습니까? p의 호출 목록에 jonsVoice와 일치하는 대리인이 없기 때문입니다.

P 두 대리자 구성된 호출 목록 갖는다하십시오 StringProcessor 객체

의 호출 방법에 tomObject

  • 한 포인팅의 세이 방법에

    • 하나를 가리키는 그 StringProcessor 생성자에 다른 StringProcessor를 전달하여 p를 초기화했기 때문입니다.

      jonsVoice = new StringProcessor(jon.Say); 
      ... 
      StringProcessor p = new StringProcessor(jonsVoice); 
      

      다른 StringProcessor 위임을 가리키는 StringProcessor 위임이 작성됩니다.

      위임자에 대한 GetInvocationList 메서드를 호출하여 대리자의 호출 목록을 검사 할 수 있습니다. 그러면 호출되는 순서대로 대리자 배열이 반환됩니다. = jonsVoice, 호출 목록 jonsVoice이하는 것처럼 (있는 오브젝트 존의 Person.Say 방법에서 가리키는 대리자를 포함하지 않습니다 - 당신은 p가 호출하면

      Delegate of StringProcessor.Invoke 
      Delegate of Person.Say 
      

      : 결과

      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를 초기화하면 StringProcessor p = jonsVoice;

      원하는 결과를 얻으실 수 있습니다.

  • +0

    감사합니다. 이제는 이해할 수 있어요. – Realeyes