2010-10-04 4 views
6

Я пытаюсь создать то, что я думаю о качестве класса трансляции, чтобы моя программа могла разговаривать с различными целевыми платформами. Каждая платформа будет обрабатываться отдельной реализацией абстрактного класса. Я упростил это ради простоты.Выполнение реализации событий в производных абстрактных классах

У меня есть абстрактный класс, с парой абстрактных методов:

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

Впоследствии класс (классы), которые вытекают из ControllerBase, и полностью реализовать эти методы:

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

До сих пор так хорошо. Для PlatformOne я вынужден определить каждый из этих методов, предписывая, как я отправлю исходящее сообщение на свою целевую платформу.

Это входящие события, которые меня достали. Мне нужно уметь поднимать события из моих производных классов. Когда я добавляю следующее controllerbase:

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

Это компилируется нормально, но я не могу поднять событие из моего производного класса без ошибки: «Событие„ControllerBase.MyEvent“может появиться только на левом с правой стороны + = или - = (кроме случаев, когда они используются внутри типа «ControllerBase») «

Итак, a) Как поднять мое событие из моего производного класса и b) может ли кто-нибудь предложить механизм для принудительное подключение определенных событий из моего производного класса (a la абстрактные функции или методы интерфейса). Спасибо назвать :)

+0

Похоже, вам нужно прочитать, как поднять события. Кроме того, если вы добавите код, относящийся к «MyEvent», который может помочь в ответе на вопрос. – Nayan

ответ

10

Самый простой способ сделать это, чтобы написать метод в базовом классе, чтобы поднять его:

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

Вы может хотите, чтобы сделать его виртуальный метод, так что вы можете переопределить это в производных классах ... это зависит от вашего варианта использования.

Обратите внимание, что это не является, заставляя реализацию чего-либо в производном классе, но я думаю, что это то, что вы на самом деле хотите.

+0

Jon - спасибо за ответ - в вашем примере, где и как вы предлагаете мне создать экземпляр MyEvent EventHander? –

+0

@Adrian: Вы можете просто объявить его как полевое событие в базовом классе, как показано в нижней части вашего вопроса. –

+0

Jon - Я считаю, что сейчас у меня все работает, и я очень благодарю вас. Остаются два вопроса: когда все сделано точно так, как описано, мне нужно сказать «var handler = MyEvent»; в отличие от «EventHandler handler = My Event», а во-вторых, я не понимаю, почему я не могу это сделать в своем производном классе - в основном, объяснение моего первоначального «события» ControllerBase.MyEvent »может появляться только в левой части ошибки + = или - = ". –

1

Создать защищенный вызов события в абстрактном классе.

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

Стандартная модель является добавление виртуального защищенного метода On<EventName>, чтобы вызвать событие

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

медведь также в виду, что события могут быть сделаны реферата или виртуальный:

public abstract event MyEventHandler MyEvent; 

хотя это обычно используется только в интерфейсах, что может быть лучше для вашего ControllerBase в зависимости от ваших точных требований:

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 
} 
Смежные вопросы