2017-04-06 55 views
0

當談到C#時,我是一個小菜鳥,這就是爲什麼我向你們所有人希望得到一些澄清。我有一個EventDispatcher類定義一個委託:委託參數 - 基類/派生類衝突

delegate void EventHandler(BaseEvent evt); 

和一些方法來使用它:

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

我也衍生事件類爲例DerivedEventBaseEvent繼承並增加自己的屬性/頂部的字段。

正如預期的那樣,我會使用它,像這樣:

AddEventListener("my_event", MyEventHandler); 

和我的處理程序方法會是這個樣子:

void MyEventHandler(BaseEvent evt) 

最後,實際的問題。爲什麼我不能定義使用派生事件類作爲參數,像這樣一個處理程序:

void MyEventHandler(DerivedEvent evt) 

我通過接口甚至嘗試但並沒有區別。我目前的方法體中鑄造實際事件類:

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

是真正的唯一途徑?希望有人能賜教:)

回答

0

當委託調用調用者允許任何BaseEvent通過。它不一定是DerivedEvent。由於調用者可能傳入的對象不是DerivedEvent,因此您的處理程序不能認爲傳入的值是DerivedEvent

可以做的是添加一個處理程序,不僅可以接受任何BaseEvent,但也可以接受其他事情。例如,您可以添加一個接受object作爲參數的處理程序,因爲處理程序調用時傳入的任何BaseEvent將是將是object

+0

我不太關注。如果我進一步下去兔子洞,我仍然會留下鑄造實際的類,事件是從沒有? –

+0

@SandroDucceschi如果調用委託的代碼實際上將提供'DerivedEvent',那麼* that *應該是委託中的參數。如果不是,那麼你就沒有辦法做,因爲這個參數實際上並不是一個「DerivedEvent」。鑄造只是讓它在運行時失敗而不是編譯時。 – Servy

+0

好,這個想法是有一個系統,我可以從'BaseEvent'傳遞任何派生類,然後調用適當的處理程序,期望所述派生類作爲參數。像這樣: 'AddEventListener(DerivedEvent.AN_EVENT,DerivedEventHandler); void DerivedEventHandler(DerivedEvent evt);' 但我希望通過定義BaseEvent作爲委託的參數,這將適用於任何此類使用。是的,如果參數是其他類型的派生事件類,它顯然會失敗。這是可以和預期的。 –