2009-06-30 8 views
35

C#에서 이벤트를 전달하는 클래스를 사용하고 있습니다. 더 적은 코드 오버 헤드가 필요한 코드를 작성하는 방법이 있는지 궁금합니다.C#에서 이벤트 전달

다음은 내가 지금까지 가지고있는 것의 예입니다.

class A 
{ 
    public event EventType EventA; 
} 

class B 
{ 
    A m_A = new A(); 
    public event EventType EventB; 

    public B() 
    { 
     m_A.EventA += OnEventA; 
    } 

    public void OnEventA() 
    { 
     if(EventB) 
     { 
     EventB(); 
     } 
    } 
} 

클래스 A는 원래 이벤트를 발생시킵니다. 클래스 B는 EventB로 전달합니다 (본질적으로 동일한 이벤트 임). 클래스 A는 다른 모듈에서 숨겨져 있으므로 EventA에 직접 등록 할 수 없습니다.

이벤트를 전달하기 위해 클래스 B의 코드 오버 헤드를 줄이는 것이 일반적입니다. 일반적으로 클래스 B의 이벤트를 실제로 처리하지 않기 때문에 작성해야 할 이벤트가 여러 개 있습니다. 이벤트를 전달하는 역할을하는 B 클래스의 많은 OnEvent() 메소드.

은 자동으로 가능하다면 어떤 방법으로 EventB에 EventA을 연결하는 것입니다, 그래서 나는 이런 식으로 뭔가있을 것 :

class B 
{ 
    A m_A = new A(); 
    public event EventType EventB; 

    public B() 
    { 
     m_A.EventA += EventB; // EventA automatically raises EventB. 
    } 
} 

내가 BTW는 C# 2.0 컴파일러를 사용하고 있습니다.

+0

위대한 질문 그렇지 않으면 메모리 누수가 발생할 수 있습니다 (객체 B는 더 이상 필요하지 않더라도 A가있는 한 메모리에 남아 있습니다). – dbkk

답변

64

은 물론 : 즉

class B 
{ 
    private A m_a = new A(); 

    public event EventType EventB 
    { 
     add { m_a.EventA += value; } 
     remove { m_a.EventA -= value; } 
    } 
} 

는 EventB 가입/탈퇴 코드는 EventA에의 가입/탈퇴 요청을 전달합니다.

그러나 EventB를 구독하는 구독자의 경우 으로 올리는 것을 허용하지 않습니다. 그것은 누군가의 주소를 대량 판매 회사에 직접 전달하는 것과 같습니다. 원래의 방식은 대량 판매 회사에 직접 가입하는 것과 같고 사람들이 메일 복사본을 보내달라고 요청하는 것과 같습니다.

+11

'B.EventB'에 대한 가입자가 잘못된 발신자 ('B'대신에 'A')를 얻는다는 것을 의미합니다. - 중요 할 수 있습니다 ... –

+3

당신이보기에 따라 "틀린"물론. 최소한 문서화 할만한 가치가있을 것입니다. –

9

IMO, 원래 코드는 (어느 정도) 정확합니다. 특히 정확한 sender (B에 이벤트에 가입하고 있다고 생각하는 사용자의 경우 B 인스턴스 여야 함)을 제공 할 수 있습니다.

이 이벤트가 가입되어 있지 않은 경우 런타임에 오버 헤드를 줄일 수있는 몇 가지 트릭이 있지만,이 코드를 추가합니다 : 당신이 EventA에서 탈퇴하는 것을 잊지합니다, 특히 이후

class B { 
    A m_A = new A(); 
    private EventType eventB; 
    public event EventType EventB { 
     add { // only subscribe when we have a subscriber ourselves 
      bool first = eventB == null; 
      eventB += value; 
      if(first && eventB != null) m_A.EventA += OnEventB; 
     } 
     remove { // unsubscribe if we have no more subscribers 
      eventB -= value; 
      if(eventB == null) m_A.EventA -= OnEventB; 
     } 
    } 

    protected void OnEventB(object sender, EventArgsType args) { 
     EventType handler = eventB; 
     if(handler !=null) { 
     handler(this, args); // note "this", not "sender" 
     } 
    } 
}