2010-12-16 92 views
3

如果我添加一個對象作爲集合的關鍵,對象是否必須滿足任何條件?我讀了一篇關於不變性的文章,其中指出哈希表中的鍵是不可變的,因此這個問題。我用於收藏的鑰匙是否需要滿足任何要求?

感謝

+1

也許你想具體說明你所指的是哪種類型的鍵控集合... Dictionary 也許? – Reddog 2010-12-16 22:52:09

回答

4

的字典鍵可以是可變的,但改變它,而它存儲在字典可能是一個非常糟糕的主意。如果密鑰的哈希值發生變化,則根據密鑰的新哈希值,字典條目可能位於錯誤的存儲桶中。這意味着你將無法再找到它。從documentation of Dictionary

只要一個對象被用作Dictionary<TKey, TValue>的關鍵,它必須在不影響其散列值任何方式更改。根據字典的相等比較器,Dictionary<TKey, TValue>中的每個密鑰必須是唯一的。一個密鑰不能是null,但值可以是,如果值類型爲TValue是一個引用類型。

0

基本上,一個鍵可以是任何對象,不能爲空。出於安全原因,密鑰應該是不可變的。

但是,你可以有:

Dictionary<Car, Color> 

Car不應該是可變的,你失去或改變它的點的標識(或哈希馬克狀態)。

0

我假設你正在使用類,而不是結構。結構的考慮因素不同。

答案是,「這取決於」。它取決於你的對象是否可以邏輯地稱爲「值類型」 - 表示邏輯數據類型的邏輯值的東西 - 或者不是。 (這有點令人困惑,因爲.NET文檔將結構體稱爲「值類型」,我在更一般的OO定義中使用該術語 - 有些類實際上是值類型。)

值類型包括像字符串,日期,點等。在我們的代碼中,我們有一個共同的值類型,它只是日期的月份和年份部分。值類型通常是不可變的。該值的標識基於其內容;如果它們具有相同的內容,則兩個不同的實例在邏輯上是「相同的」。您可以有兩個不同的字符串實例,但如果它們包含相同的字符序列,則它們是「相同」值。

另一方面,由於缺乏更好的術語,我將稱之爲「對象」:不代表邏輯值的事物。這些將是字符串構建器,文件流,陣列,客戶,訂單和產品等。這些不是具體的價值。該對象的身份是基於它的實例:兩個不同的實例不是「相同的」;他們不同,因爲他們是不同的實例。

因此,您的問題的答案取決於您的對象是否代表上述定義下的「值類型」或「對象」。

如果它們是「值類型」,那麼您的班級需要覆蓋EqualsGetHashCodeEquals應該返回true,如果兩個實例是相同的類型並且具有相同的內容。GetHashCode應該返回值的內容的散列;如果兩個實例「相同」,則它們必須返回相同的哈希碼。

如果它們是「對象」,則從System.Object繼承的EqualsGetHashCode實現將使用引用相等性來確定兩個對象是否「相同」(並因此應該在對象中被視爲相同的鍵)字典),這是你想要的。所以只要你不從繼承的東西本身覆蓋EqualsGetHashCode,你不需要做任何特殊的事情來使用「對象」作爲關鍵。

相關問題