2009-06-30 34 views
35

Tôi đang sử dụng lớp chuyển tiếp sự kiện trong C#. Tôi đã tự hỏi nếu có một cách để làm nó đòi hỏi ít chi phí mã hơn.Sự kiện chuyển tiếp trong C#

Đây là ví dụ về những gì tôi có cho đến thời điểm này.

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

Lớp A tăng sự kiện ban đầu. Lớp B chuyển tiếp nó như EventB (mà về cơ bản là cùng một sự kiện). Lớp A bị ẩn khỏi các mô-đun khác để họ không thể đăng ký trực tiếp EventA.

Những gì tôi đang cố gắng làm là giảm chi phí mã trong lớp B để chuyển tiếp sự kiện, như thường không có sự xử lý thực sự của các sự kiện trong lớp B. Ngoài ra tôi sẽ có một số sự kiện khác nhau nhiều phương thức OnEvent() trong lớp B chỉ phục vụ để chuyển tiếp các sự kiện.

Có thể tự động liên kết EventA để EventB một cách nào đó, vì vậy tôi muốn có một cái gì đó như thế này:

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

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

Tôi đang sử dụng một trình biên dịch C# 2.0 btw.

+0

Great câu hỏi, đặc biệt là kể từ khi bạn không nên quên để bỏ đăng ký từ EventA , nếu không có thể có một rò rỉ bộ nhớ (đối tượng B của bạn sẽ vẫn còn trong bộ nhớ miễn là A là, ngay cả khi nó không còn cần thiết). – dbkk

Trả lời

64

Tuyệt đối:

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

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

Nói cách khác, các EventB thuê bao/code việc hủy đăng ký chỉ cần vượt qua đăng ký/đề nghị huỷ đăng ký trên để EventA.

Lưu ý rằng điều này không cho phép bạn tăng sự kiện chỉ cho những người đăng ký đã tham gia EventB, tuy nhiên. Nó giống như chuyển địa chỉ của ai đó trực tiếp lên một công ty tiếp thị đại chúng, trong khi cách ban đầu của bạn giống như tự đăng ký với công ty tiếp thị đại chúng và cho phép mọi người yêu cầu bạn gửi bản sao của thư cho họ.

+11

Điều đó có nghĩa là người đăng ký 'B.EventB' nhận sai người gửi (' A' thay vì 'B'), mặc dù - điều này có thể quan trọng ... –

+3

Đúng, đúng ... tùy thuộc vào những gì bạn xem là "sai" tất nhiên. Có lẽ giá trị tài liệu ít nhất. –

9

IMO, mã ban đầu của bạn (chính xác hoặc ít hơn) chính xác. Đặc biệt, nó cho phép bạn cung cấp chính xác sender (phải là phiên bản B cho những người nghĩ rằng họ đang đăng ký một sự kiện trên B).

Có một số thủ thuật để làm giảm các chi phí trong thời gian chạy nếu sự kiện này không được đăng ký, nhưng điều này cho biết thêm hơn mã:

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" 
     } 
    } 
} 
Các vấn đề liên quan