2013-04-23 91 views
7

如果您有對象Dictionary<k, v> myDictionary,那麼myDictionary.Values將是Dictionary<k, v>.ValueCollection類型,而myDictionary.Keys將是Dictionary<k, v>.KeyCollection類型。myCustomDictionary.Values應返回什麼類型?

我不明白爲什麼類型的myDictionary.Values是不是像IEnumerable<v>,IList<v>或其他東西。

現在,考慮到這一點,如果我創建一個自定義類型的字典; Dictionary2<k1, k2, v>,應該myCustomDictionary.Values返回IEnumerable<v>,或ValueCollection的自定義工具?更重要的是,爲什麼?

+2

非常有趣的問題:) – 2013-04-23 14:22:23

回答

5

請注意,Dictionary<TKey, TValue>.ValueCollection確實實施ICollection<TValue>,因此也IEnumerable<TValue>

之所以屬性是類型它的方式很可能出於性能的考慮:因爲這個類的方法不是虛擬的,他們可以準確地JIT編譯過程中解決,而不需要虛函數表查找每個方法,在運行時調用。這有效地從您調用集合的每種方法中移除一個間接級別。 (它也給了JIT內聯這些方法調用的選項!)

當然,如果需要,您可以隱式地將對象轉換爲ICollection<TValue>,所以這裏沒有功能損失,只是一些(微)優化。

在你的情況下,沒有理由不能返回ICollection<TValue>,但如果你願意,你可以返回一個更具體的類型。如果你這樣做,那麼你就必須明確地實現接口屬性IDictionary<TKey, TValue>.Values滿足該接口:

private ValueCollection valueCollection; 

public ValueCollection Values 
{ 
    get { return valueCollection; } 
} 

ICollection<TValue> IDictionary<TKey, TValue>.Values 
{ 
    get { return valueCollection; } 
} 

這正確意味着,如果他們使用類型的引用任何性能優勢將只提供給消費者的類作爲你的收藏類型;如果他們參考IDictionary<TKey, TValue>將不會有性能優勢,因爲他們不得不選擇,但無論如何通過ICollection<TValue>訪問您的價值收藏。

在我的工作中,我沒有發現性能差異足夠大,以保證返回任何比ICollection<TValue>更具體的東西。記住:永遠都是基準,永遠不會過早優化。

+1

什麼,這個答案有很多的信息。非常感謝先生! – Tipx 2013-04-23 14:40:43

+0

'List '和'Dictionary '是'IList '和'IDictionary '最經常使用的實現。因此,防止不必要的接口調度調用會在整個.NET生態系統中產生綜合影響,並有助於Java永遠無法觸及的移動設備功耗優勢(由於它們在基礎結構類中過度使用可覆蓋的方法)。 – 2013-04-23 15:56:57

1

Dictionary<k, v>.ValueCollection implements IEnumerable<v> and Dictionary<k, v>.KeyCollection implements IEnumerable<k>。它不像返回的結果不是可枚舉的。

通過返回實現IEnumerable的實際類,而不是將結果輸入爲IEnumerable,它們還能夠包含一些附加功能。例如,這兩個集合都有一個Count屬性,不易從任何IEnumerable訪問。

+2

請注意'ICollection '有一個Count屬性,而'IDictionary .Values'返回'ICollection '。因此,* IDictionary * * *的任何*實現都必須返回支持Count屬性的'Values'對象。更具體的'Dictionary .Values'類型沒有以任何方式提供我可以看到的額外功能。 – cdhowie 2013-04-23 14:25:45