2017-04-06 3 views
0

Ich bin ein bisschen wie ein Anfänger, wenn es um C# geht, weshalb ich zu euch alle in der Hoffnung auf etwas Klärung komme. Ich habe eine Eventdispatcher-Klasse, die einen Delegaten definiert:Delegiertenargumente - Basis-/abgeleitete Klassen Konflikt

delegate void EventHandler(BaseEvent evt); 

und ein paar Methoden, es zu benutzen:

void AddEventListener(string event_name, EventHandler handler) 
void RemoveEventListener(string event_name, EventHandler handler = null) 
void DispatchEvent(BaseEvent evt) 

Ich habe auch Ereignisklassen abgeleitet für Beispiel DerivedEvent, die von BaseEvent erbt und fügt ihre eigenen Eigenschaften/Felder an der Spitze.

AddEventListener("my_event", MyEventHandler); 

und meine Handler-Methode in etwa so aussehen würde:

void MyEventHandler(BaseEvent evt) 

schließlich das eigentliche Problem

Wie erwartet ich es wie so verwenden würde. Warum kann ich nicht definieren einen Handler, der die abgeleitete Ereignisklasse als Argument verwendet, etwa so:

void MyEventHandler(DerivedEvent evt) 

Ich habe sogar über Schnittstellen versucht, aber das machte keinen Unterschied. Ich bin derzeit Casting innerhalb der Methode-Körper der tatsächlichen Event-Klasse:

... 
DerivedEvent actualEvent = (DerivedEvent)evt; 
... 

Ist das wirklich der einzige Weg? Hoffentlich kann jemand mich erleuchten :)

Antwort

0

Wenn der Delegat angerufen wird, darf der Anrufer beliebigBaseEvent übergeben. Es ist nicht unbedingt ein DerivedEvent. Da der Aufrufer möglicherweise ein Objekt übergibt, das kein DerivedEvent ist, kann Ihr Handler nicht davon ausgehen, dass der übergebene Wert ein DerivedEvent ist.

Was Sie können Do ist ein Handler hinzufügen, die nicht nur alle BaseEvent akzeptieren kann, sondern auch andere Dinge. Sie könnten z. B. einen Handler hinzufügen, der object als Parameter akzeptiert, da alle BaseEvent, die übergeben werden, wenn der Handler aufgerufen wird ein object sein wird.

+0

Ich folge nicht ganz. Wenn ich weiter unten in das Kaninchenloch gehe, werde ich immer noch mit dem Casting zur tatsächlichen Klasse verlassen, dass das Event von nein ist? –

+0

@SandroDucceschi Wenn der Code, der den Delegaten aufruft, tatsächlich ein 'DerivedEvent' liefert, dann sollte * das * der Parameter im Delegaten sein. Wenn dies nicht der Fall ist, können Sie nichts tun, da der Parameter kein "DerivedEvent" ist. Casting lässt es nur zur Laufzeit statt zur Kompilierzeit fehlschlagen. – Servy

+0

Nun ist die Idee, ein System zu haben, wo ich jede abgeleitete Klasse von 'BaseEvent' übergeben kann, die dann den passenden Handler aufrufen wird, der diese abgeleitete Klasse als Argument erwartet. So: 'AddEventListener (DerivedEvent.AN_EVENT, DerivedEventHandler); void DerivedEventHandler (DerivedEvent evt); ' Noch hatte ich gehofft, indem ich das BaseEvent als das Argument des Delegierten definierte, dass das für jede solche Verwendung funktionieren würde. Und ja, klar, es würde scheitern, wenn das Argument von irgendeiner anderen abgeleiteten Ereignisklasse wäre. Was ist in Ordnung und erwartet. –