2010-10-04 32 views
6

Tôi đang cố gắng tạo ra những gì tôi đang nghĩ đến như một lớp dịch, để chương trình của tôi có thể nói chuyện với nhiều nền tảng đích khác nhau. Mỗi nền tảng sẽ được xử lý bằng cách thực hiện riêng biệt một lớp trừu tượng. Tôi đã bỏ mọi thứ xuống vì mục đích đơn giản.Ép buộc thực hiện các sự kiện trong các lớp trừu tượng bắt nguồn

Tôi có một lớp trừu tượng, với một vài phương pháp trừu tượng:

abstract class ControllerBase 
{ 
    public abstract bool EnableDTMFDetection(string CallID, Party Party); 
    public abstract bool DisableDTMFDetection(string CallID, Party Party); 
} 

Sau đó một lớp (lớp) mà bắt nguồn từ ControllerBase, và thực hiện đầy đủ các phương pháp đó:

class PlatformOne : ControllerBase 
{ 
    public override bool EnableDTMFDetection(string CallID, Party Party) 
    { 
     // Do Stuff 
     return true; 
    } 

    public override bool DisableDTMFDetection(string CallID, Party Party) 
    { 
     // Do Stuff 
     return true; 
    } 
} 

Cho đến nay rất tốt Đối với PlatformOne, tôi buộc phải xác định từng phương pháp đó, quy định cách tôi sẽ gửi một thông báo gửi đi đến nền tảng đích của mình.

Đó là các sự kiện đã đến với tôi. Tôi cần để có thể nâng cao sự kiện từ bên trong các lớp học có nguồn gốc của tôi. Khi tôi thêm dòng sau vào controllerbase:

public delegate void MyEventHandler(object sender, EventArgs e); 
    public event MyEventHandler MyEvent; 

Nó biên dịch tốt, nhưng tôi không thể nâng cao sự kiện từ bên trong lớp được thừa kế của tôi mà không có lỗi: "Sự kiện 'ControllerBase.MyEvent' chỉ có thể xuất hiện ở bên trái Mặt bên của + = hoặc - = (trừ khi được sử dụng từ bên trong loại 'ControllerBase') "

Vì vậy, a) Làm cách nào để tăng sự kiện của mình từ bên trong lớp dẫn xuất của tôi, và b) thực thi việc kết nối các sự kiện được chỉ định từ bên trong lớp dẫn xuất của tôi (một hàm trừu tượng la hoặc các phương thức giao diện). Cảm ơn bạn gọi :)

+0

Dường như bạn cần đọc cách tăng sự kiện. Ngoài ra, nếu bạn thêm mã liên quan đến "MyEvent", điều đó có thể giúp trả lời câu hỏi. – Nayan

Trả lời

10

Cách đơn giản nhất để làm điều này là để viết một phương thức trong lớp cơ sở của bạn để nâng cao nó:

protected void OnMyEvent(EventArgs e) 
{ 
    // Note the copy to a local variable, so that we don't risk a 
    // NullReferenceException if another thread unsubscribes between the test and 
    // the invocation. 
    EventHandler handler = MyEvent; 
    if (handler != null) 
    { 
     handler(this, e); 
    } 
} 

Bạn thể muốn làm cho nó một phương pháp ảo, do đó bạn có thể ghi đè nó trong các lớp dẫn xuất ... nó phụ thuộc vào trường hợp sử dụng của bạn.

Lưu ý rằng điều này không phải là buộc thực hiện bất kỳ điều gì trong lớp dẫn xuất - nhưng tôi nghĩ đó là những gì bạn thực sự muốn.

+0

Jon - cảm ơn bạn đã trả lời - trong ví dụ của bạn, ở đâu và làm thế nào bạn đề xuất tôi tạo ra trường hợp MyEvent của EventHander? –

+0

@Adrian: Bạn chỉ có thể tuyên bố nó là sự kiện giống như trường trong lớp cơ sở, như bạn đã hiển thị ở gần cuối câu hỏi của mình. –

+0

Jon - Tôi tin rằng tôi có mọi thứ đang hoạt động, và tôi cảm ơn rất nhiều. Vẫn còn hai câu hỏi: Khi được thực hiện chính xác như mô tả, tôi cần phải nói "var handler = MyEvent;" trái ngược với "EventHandler handler = My Event;" và thứ hai tôi không hiểu tại sao tôi không thể làm điều này trong lớp xuất phát của mình - về cơ bản là lời giải thích cho "Sự kiện" ControllerBase.MyEvent "ban đầu của tôi chỉ có thể xuất hiện ở phía bên trái của lỗi + = hoặc - = ". –

1

Tạo trình kích hoạt sự kiện được bảo vệ trong lớp trừu tượng.

protected void InvokeMyEvent(EventArgs args) 
{ 
    var handler = MyEvent; 
    if (hander != null) 
     handler(this, args); 
} 
3

Các mô hình tiêu chuẩn là thêm một On<EventName> phương pháp bảo vệ ảo để nâng cao một sự kiện

protected virtual OnMyEvent(EventArgs e) { 
    var h = MyEvent; 
    if (h != null) 
     h(this, e); 
} 

Cũng nhớ rằng các sự kiện có thể được thực hiện trừu tượng hoặc ảo:

public abstract event MyEventHandler MyEvent; 

mặc dù điều này chỉ thường được sử dụng trong giao diện, điều này có thể tốt hơn cho ControllerBase tùy thuộc vào yêu cầu chính xác của bạn:

public interface IController { 
    event MyEventHandler MyEvent; 
    bool EnableDTMFDetection(string CallID, Party Party); 
    bool DisableDTMFDetection(string CallID, Party Party); 
} 

public PlatformOne : IControllerBase 

    // yadda yadda... 

    public event MyEventHandler MyEvent; 

    // members of PlatformOne can invoke MyEvent as a normal delegate 
} 
Các vấn đề liên quan