2010-10-04 11 views
6

Sto cercando di creare quello che sto pensando come una classe di traduzione, in modo che il mio programma possa parlare a una varietà di piattaforme di destinazione. Ogni piattaforma sarà gestita da un'implementazione separata di una classe astratta. Ho ridotto le cose per semplicità.Applicazione dell'implementazione di eventi nelle classi astratte derivate

devo una classe astratta, con un paio di metodi astratti:

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

Successivamente una classe (classi) che derivano da ControllerBase, e attuare pienamente quei metodi:

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

Finora così buono. Per PlatformOne sono costretto a definire ciascuno di questi metodi, prescrivendo come invierò un messaggio in uscita alla mia piattaforma di destinazione.

Sono gli eventi in arrivo che mi hanno colpito. Devo essere in grado di generare eventi dalle mie classi derivate. Quando aggiungo quanto segue per controllerbase:

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

Si compila bene, ma non posso generare l'evento da dentro il mio classe derivata senza l'errore: "L'evento 'ControllerBase.MyEvent' può apparire solo a sinistra lato mano di + = o - = (tranne quando usato all'interno del tipo 'ControllerBase') "

Quindi, a) Come posso aumentare il mio evento dalla mia classe derivata eb) qualcuno può suggerire un meccanismo per imporre il cablaggio di eventi specifici all'interno della mia classe derivata (funzioni astratte o metodi di interfaccia). Grazie :) chiama

+0

Sembra che tu abbia bisogno di leggere come aumentare gli eventi. Inoltre, se aggiungi il codice relativo a "MyEvent", ciò potrebbe aiutarti a rispondere alla domanda. – Nayan

risposta

10

Il modo più semplice per farlo è quello di scrivere un metodo nella classe base per sollevarlo:

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

È può vuole renderlo un metodo virtuale in modo da poter ignorare nelle classi derivate ... dipende dal tuo caso d'uso.

Si noti che questo non è forzare un'implementazione di qualsiasi cosa nella classe derivata, ma penso che sia ciò che si desidera effettivamente.

+0

Jon - grazie per la risposta - nel tuo esempio, dove e come stai suggerendo di creare l'istanza MyEvent di EventHander? –

+0

@Adrian: puoi solo dichiararlo come un evento simile a un campo nella classe base, come mostrato nella parte inferiore della domanda. –

+0

Jon - Credo di avere cose che funzionano ora, e ti ringrazio molto. Rimangono due domande: una volta fatto esattamente come descritto, devo dire "var handler = MyEvent;" al contrario di "EventHandler handler = My Event;", e in secondo luogo non riesco a capire perché non posso farlo nella mia classe derivata - fondamentalmente una spiegazione per la mia iniziale "L'evento" ControllerBase.MyEvent "può apparire solo sul lato sinistro di + = o - = "errore. –

1

Creare un invocator evento protetto nella classe astratta.

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

Il modello standard è di aggiungere un metodo virtuale protetto On<EventName> di sollevare un evento

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

Anche tenere a mente che gli eventi possono essere fatte astratto o virtuale:

public abstract event MyEventHandler MyEvent; 

anche se questo è generalmente utilizzato solo nelle interfacce, che potrebbero essere migliori per il tuo ControllerBase a seconda dei tuoi esatti requisiti:

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 
} 
Problemi correlati