2010-10-04 29 views
6

J'essaie de créer ce que je considère comme une classe de traduction, afin que mon programme puisse parler à une variété de plates-formes cibles. Chaque plate-forme sera gérée par une implémentation distincte d'une classe abstraite. J'ai paré les choses pour des raisons de simplicité.Mise en œuvre de l'implémentation d'événements dans des classes abstraites dérivées

J'ai une classe abstraite, avec quelques méthodes abstraites:

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

Par la suite une classe (classes) qui dérivent de ControllerBase et mettre pleinement en œuvre ces méthodes:

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

Jusqu'à présent tellement bon. Pour PlatformOne, je suis obligé de définir chacune de ces méthodes, en prescrivant comment je vais envoyer un message sortant à ma plateforme cible.

Ce sont les événements entrants qui m'ont eu. Je dois pouvoir élever des événements à l'intérieur de mes classes dérivées. Quand j'ajoute ce qui suit à controllerbase:

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

Il compile très bien, mais je ne peux pas soulever l'événement à l'intérieur de ma classe dérivée sans l'erreur: « L'événement « ControllerBase.MyEvent » ne peut apparaître sur la gauche côté de + = ou - = (sauf si utilisé du type 'ControllerBase') "

Donc, a) Comment puis-je élever mon événement de l'intérieur de ma classe dérivée, et b) quelqu'un peut-il suggérer un mécanisme pour l'application du câblage des événements spécifiés à partir de ma classe dérivée (fonctions abstraites ou méthodes d'interface). Thank vous appelez :)

+0

Il semble que vous ayez besoin de lire comment déclencher des événements. De plus, si vous ajoutez le code associé à "MyEvent", cela peut vous aider à répondre à la question. – Nayan

Répondre

10

La façon la plus simple de le faire est d'écrire une méthode dans votre classe de base pour le porter:

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

Vous peut vouloir en faire une méthode virtuelle de sorte que vous pouvez remplacer dans les classes dérivées ... cela dépend de votre cas d'utilisation.

Notez que ce n'est pas forçant une implémentation de n'importe quoi dans la classe dérivée - mais je pense que c'est ce que vous voulez réellement.

+0

Jon - merci pour la réponse - dans votre exemple, où et comment suggérez-vous que je crée l'instance MyEvent de EventHander? –

+0

@Adrian: Vous pouvez simplement le déclarer comme un événement semblable à un champ dans la classe de base, comme vous l'avez montré au bas de votre question. –

+0

Jon - Je crois que j'ai des choses qui fonctionnent maintenant, et je vous remercie beaucoup. Deux questions demeurent: Quand fait exactement comme décrit, je dois dire "var handler = MyEvent;" par opposition à "EventHandler handler = Mon événement;", et d'autre part je suis à plat comprendre pourquoi je ne peux pas le faire dans ma classe dérivée - essentiellement une explication pour mon initiale "L'événement 'ControllerBase.MyEvent' ne peut apparaître sur le côté gauche de + = ou - = "erreur. –

1

Créez un invocateur d'événement protégé dans la classe abstraite.

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

Le modèle standard est d'ajouter une méthode protégée virtuelle On<EventName> pour déclencher un événement

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

Gardez aussi à l'esprit que les événements peuvent être abstraite ou virtuelle:

public abstract event MyEventHandler MyEvent; 

bien ce n'est généralement utilisé dans les interfaces, ce qui pourrait être mieux pour votre ControllerBase en fonction de vos besoins exacts:

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 
}