2017-03-16 13 views
1

我有它可以在幾個不同類型的對象的集合運作,對他們採取適當行動的靜態方法的類:如何處理一個IDictionary只有強類型的鍵?

static void DoSomething(ICollection<TypeA> things) 
{ 
    // Do something with TypeA elements 
} 

static void DoSomething(ICollection<TypeB> things) 
{ 
    // Do something with TypeB elements 
} 

其他地方在我的代碼有很多,其使用兩種TypeA字典或TypeB爲他們的鑰匙,併爲他們的價值觀的各種類型。我最後撥打了DoSomething(dictionary.Keys),我認爲接受dictionary並將.Keys集合傳遞給適當的過載的方法會更好。

看來我可以做到這一點,如果我強類型的字典:

static void DoSomething(IDictionary<TypeA,object> dictionary) 
{ 
    DoSomething(dictionary.Keys); 
} 

但後來我需要爲每個IDictionary<TypeA,TValues>,它可能會遇到過載,即使該方法不需要知道什麼TValues是工作。

或者我似乎能夠接受一個通用IDictionary,但隨後不得不重鑄Keys到合適的類型:

static void DoSomething(IDictionary dictionary) 
{ 
    DoSomething((ICollection<TypeA>) dictionary.Keys); 
} 

這似乎並不明智,因爲使用字典不支持的關鍵類型的呼叫贏得」翻譯編譯器,我大概不得不依靠Reflection來選擇正確的過載。

我錯過了一個更好的選擇嗎?

+1

確實typeA和typeB共享一個接口或基類?你可以使用泛型 –

+0

你介意使用'dynamic'嗎? static void DoSomething(IDictionary dictionary)' – Quantic

+0

我剛試過這個,解釋器似乎沒有識別到​​對這樣聲明的方法的調用。所述「不能從IDictionary '轉換爲'ICollection '」 - 即試圖將它傳遞給不同的過載。我對「動態」不熟悉 - 聲明或調用是否需要滿足其他條件? – Will

回答

2

你可以創建一個接受的字典值的類型的類型參數的一般方法:

static void DoSomething<TVALUE>(IDictionary<TypeA, TVALUE> dictionary) 
{ 
    DoSomething(dictionary.Keys); 
} 
+0

如果TypeA和TypeB不共享相同的interace,是不是他需要繼續鑄造?如果不是 –

+0

磨片OP說,他將只訪問對象接口「但後來我需要爲每一個的IDictionary <類型A,TValues>,它可能會遇到過載,即使該方法不需要知道TValues是什麼工作。」我想,他要盡一切方法之一 –

+1

@ Gonzalo.-他需要兩種類型A和類型B單獨的方法(有單獨的'DoSomething的(ICollection的)'和'DoSomething的(ICollection的'方法。據我瞭解了問題,OP不希望爲'TVALUE'創建單獨的方法,但對於TypeA和TypeB單獨使用方法很好。 – Markus

0

的最好的事情(如果你有超過TypeATypeB控制)是使兩種類型實現這樣一個接口:

interface IDoSomething 
{ 
    void DoSomething(); 
} 

...並將字典更改爲Dictionary<IDoSomething, T>

然後,您可以簡單地遍歷字典鍵並在每個字段上調用DoSomething()

其他解決方案往往違反Open/Closed Principle。例如,如果你這樣做as Markus suggested然後某處,你會用這樣的開關/系列if語句的拉閘:

if (key is TypeA) 
    DoSomething<TypeA>(key); 
else if (key is TypeB) 
    DoSomething<TypeB>(key); 
else 
    throw new Exception(); 

這是一個代碼味道,並指出違反了這一原則。例如,當你需要將一個TypeC類型的密鑰放入字典時會發生什麼?你必須記住改變這個代碼所在的地方(因此這個代碼沒有被修改)。如果你忘記了,那麼這是一個運行時錯誤,而不是編譯錯誤。而且隨着代碼的擴展,問題只會變得更糟,因爲這些switch/if語句開始出現在所有地方。

如果你不能使TypeATypeB實現相同的接口,那麼也許有另一種方式重構SOLID principles。如果您對這個問題有任何疑問,我相信SO社區會很樂意回答一個單獨的問題。

+0

Markus答案中的方法仍然是強類型爲'TypeA'類型的鍵,所以它不會導致運行時類型邏輯,它只需要對這種形式的單獨聲明,用於我想要處理的所有類型的字典鍵 通過這種方式。由於'DoSomething'已經有'ICollection的'和'ICollection的'獨立宣言,這是可以接受的,從事情迄今已經組建方式的預期。確實,修改屬於受支持集合的元素的類型將更具可擴展性,但這不是特定於擴展到字典鍵的。 – Will

相關問題