2008-12-02 89 views
1

我有一個接口方法在C#中,如何在不知道類型的情況下向下轉換以前上傳的對象?

public void Execute(ICommand command); 

其需要的ICommand已知亞型傳遞給apropriate Handle(SpecificCommand command)方法實現,做未知類型的一些通用的處理。我要尋找一個通用的(即不需要巨大的switch)這樣做,類似的方法來

Handle(command as command.GetType()); // this obviously does not compile 

我知道我能以某種方式註冊的處理程序,例如將它們作爲委託存儲在字典中,但這仍然需要重複處理邏輯(一次在特定的Handle(...)方法簽名中,一次在委託請求中)。如果我通過反思來檢查我的課程來填充詞典(查找Handle(XXX command)方法),我會得到一個性能優勢。總結:如何在不知道編譯時的哪種類型的情況下,通過調用Execute(ICommand command)來調用一個需要具體類型的方法。

回答

5

轉換是在編譯時發出的,因此您需要在編譯時知道類型。重載也是在編譯時確定的 - 所以當你真正知道要使用的具體類型時,就太遲了。

我沒有看到你實際上使用委託來複制任何邏輯。或者,如果您使用反射來完成它,則可以使用Delegate.CreateDelegate輕鬆構建委託 - 您只會獲得一次性能優勢,之後它將非常快速。請參閱我的blog entry about Delegate.CreateDelegate瞭解更多信息。

我想我會決定使用一個手工建立的字典或基於我有多少種方法以及它們多久更換一次的反射構建的字典。你可能會發現KeyedByTypeCollection有用的字典。

2

你不能,爲什麼你想?

這就是我們擁有多態性的全部原因。如果您想要具有特定於某些類型的自定義行爲,那麼行爲應該存在於類型本身中,並通過在基類類型中聲明的函數來調用。

+0

我的問題是,我想要自定義行爲,不僅具體到某種類型,還特定於此類型的消費者。 – skolima 2008-12-02 11:22:02

9

嗯,「正確」的答案是Handle()應該是ICommand中的一個方法,所以你可以說不是Handle(command),而是command.Handle()

+0

問題是Execute()是一種接口方法,各種實現者將以不同的方式處理這些命令。而且我不希望每次添加命令時都在界面中添加方法,因爲這會每次破壞執行程序。 – skolima 2008-12-02 09:10:24

+0

@skolima我認爲你需要更具體,我同意詹姆斯的批評,幾乎可以肯定你想在這裏使用多態,而不是一些可怕的kludgey switch語句或一些這樣的。將代碼封裝在它所屬的位置。 – Wedge 2008-12-02 09:39:25

1

我已經嘗試了一種可以使用Double Dispatch(http://en.wikipedia.org/wiki/Double_dispatch)的方法,但是似乎有一種情況,實現ICommand的類的數量和執行Execute()的類的數量在運行時會有所不同或者,至少在編譯&運行時間,這本質上是相同的事情),所以唯一的解決方案,我可以看到它使用字典作爲Jon Skeet提供的。

相關問題