2009-02-21 8 views
22

한 이벤트의 가입자를 다른 이벤트로 복사해야합니다. MyEvent [0]이 대리자를 반환하는 것과 같이 이벤트의 구독자를 얻을 수 있습니까?이벤트 구독자는 어떻게 만듭니 까?

이것이 가능하지 않은 경우 추가 접근자를 사용하여 목록에 대리인을 추가 할 수 있습니다. 그게 최선의 해결책일까요?

답변

20

C# 이벤트/대리자는 멀티 캐스트이므로 대표는 자체 인입니다. 클래스 내에서 개별 발신자를 얻을, 당신은 사용할 수 있습니다

if(field != null) { // or the event-name for field-like events 
    // or your own event-type in place of EventHandler 
    foreach(EventHandler subscriber in field.GetInvocationList()) 
    { 
     // etc 
    } 
} 

을하지만, 한 번에 모든 할당, 바로 사용 + = 또는 직접 할당 : 경우

SomeType other = ... 
other.SomeEvent += localEvent; 
+0

그 점을 지적 해 주셔서 감사합니다. 내 코드의 이벤트에 가장 적합합니다. – weiqure

+0

고마워요. 구독 된 이벤트를 즐기지 않는 바이너리 직렬화를 통한 객체 복제에 대한 좋은 해결 방법이 필요했습니다. 그렇지 않으면 수백 개의 클래스로 ICloneable을 구현해야했습니다. – user1039513

3

업데이트 (의견 제공 담당자) : 위임자 권한은 복제가 할당을 넘어서 아무것도 수행하지 않는다는 것을 의미합니다.

하나는 쓸 때 :

myDelegate += AHandler 

완전히 새로운 대리자 인스턴스를 생성 myDelegate에 할당됩니다.

따라서 아래 코드는 복제 호출없이 정확히 동일하게 작동합니다.


MulticastDelegate (기본 유형)에는 Clone 메소드가 있습니다.

기본 위임자를 얻으려면 이벤트 키워드가 생성하는 일반적인 도우미를 피하고 직접 관리해야합니다 (사용자 지정 추가 및 제거 접근 자).

이를 표시하려면 : 이벤트가 다른 클래스에 의해 출판 하나입니다

 
    class Program { 
     public delegate void MyDelegate(string name); 

     public event MyDelegate EventOne; 

     public void HandlerOne(string name) { 
      Console.WriteLine("This is handler one: {0}", name); 
     } 
     public void HandlerTwo(string name) { 
      Console.WriteLine("This is handler two: {0}", name); 
     } 
     public void HandlerThree(string name) { 
      Console.WriteLine("This is handler three: {0}", name); 
     } 

     public void Run() { 
      EventOne += HandlerOne; 
      EventOne += HandlerTwo; 
      Console.WriteLine("Before clone"); 
      EventOne("EventOne"); 

      
            
 
  
             MyDelegate eventTwo = (MyDelegate)EventOne.Clone();
            
  
      MyDelegate eventTwo = EventOne; 
      Console.WriteLine("After 
            
 
  
             clone
            
 copy"); 
      EventOne("EventOne"); 
      eventTwo("eventTwo"); 

      Console.WriteLine("Change event one to show it is different"); 
      EventOne += HandlerThree; 
      EventOne("EventOne"); 
      eventTwo("eventTwo"); 
     } 

     static void Main(string[] args) { 
      (new Program()).Run(); 
     } 
    } 
+0

클론 자체는 상대적으로 중요하지 않습니다. 대리자는 변경할 수 없으므로 위임 참조를 복사 할 수 있습니다. –

+0

샘플에서와 같이 원본 또는 사본을 개별적으로 수정하지 않는 한. – Richard

+0

리차드 - 아니요, Clone() 단계가 없어도 똑같이 ** 작동합니다. –

13

경우, 당신은 할 수 없습니다 - 이상,하지 신뢰성. 이벤트를 대리자 변수로 생각하는 경우가 많지만 실제로는 이벤트의 추가 및 제거 (구독 및 구독 취소)와 같은 두 가지 방법이 있습니다.

이벤트를 게시하는 자신의 코드라면 쉽게 추가 할 수 있습니다. 추가/제거 접근자는 원하는대로 수행 할 수 있습니다.

my article on events을보고 도움이되는지 확인하십시오. 그렇지 않은 경우 수정할 수있는 코드와 그렇지 않은 코드를 지정하여 원하는 작업에 대한 자세한 정보를 제공하십시오.

1

당신이 조사 할 필요가 외부 클래스의 가입자 '이벤트 :

EventHandler e = typeof(ExternalClass) 
    .GetField(nameof(ExternalClass.Event), BindingFlags.Instance | BindingFlags.NonPublic) 
    .GetValue(instanceOfExternalClass) as EventHandler; 
if (e != null) 
{ 
    Delegate[] subscribers = e.GetInvocationList(); 
} 
관련 문제