c# - 哈希码作为键控集合中的键

标签 c# .net hash

据我(认为)所知,Dictionary 是作为散列表实现的,其中散列码用于标识存储桶,然后在存储桶中搜索键。

在我看来,这意味着对象的哈希码在我的程序单次运行期间保持稳定(粗略地说)。

现在,这里

http://msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx

我读了

“哈希码用于在基于哈希表的集合中高效插入和查找。哈希码不是永久值。因此: [...] 不要使用哈希码作为键从键控集合中检索对象。

谁能给我解释一下这是什么意思?

最佳答案

当文档谈到“键控集合”时,它们与字典的含义不同。要深入了解它的实际含义,请注意实际上有一个 KeyedCollection。基类:http://msdn.microsoft.com/en-us/library/ms132438%28v=vs.110%29.aspx

关键段落是这样的:

Unlike dictionaries, an element of KeyedCollection<TKey, TItem> is not a key/value pair; instead, the entire element is the value and the key is embedded within the value. For example, an element of a collection derived from KeyedCollection<String,String> (KeyedCollection(Of String, String) in Visual Basic) might be "John Doe Jr." where the value is "John Doe Jr." and the key is "Doe"; or a collection of employee records containing integer keys could be derived from KeyedCollection<int,Employee>. The abstract GetKeyForItem method extracts the key from the element.

因此,键控集合是对象的集合以及从每个对象中提取键的方法。从概念上讲,这类似于数据库中的表,您可以在其中定义一个主键,它是整个记录的一个子集。

所以考虑到这一点,答案就变得相对清楚了。正如其他人所说,哈希码相等并不意味着对象相等。但是键控集合中的键——就像数据库表中的主键——应该唯一地标识确切的对象。因此哈希冲突的可能性使它们不适合用于此目的。

此外,即使在 Dictionary 中,使用对象作为键和使用相同对象的哈希码作为键之间有一个重要的区别。如果两个对象发生哈希冲突但不相等,则 Dictionary仍会将它们存储为两个单独的 key 。这就是为什么重写 GetHashCode只返回 1 总是有效的(虽然显然不利于性能)。作为演示:

var dict = new Dictionary<MyClass, string>();
var hashDict = new Dictionary<int, string>();

dict[myObj1] = "One";
hashDict[myObj1.GetHashCode()] = "One";
dict[myObj2] = "Two";
hashDict[myObj2.GetHashCode()] = "Two";

Console.Out.WriteLine(dict[myObj1]);  //Outputs "One"
Console.Out.WriteLine(hashDict[myObj1.GetHashCode()]); //Outputs "Two"

(myObj1myObj2MyClass 的实例,它们具有相同的哈希码但不比较相等)

关于c# - 哈希码作为键控集合中的键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24026104/

相关文章:

c# - 如何在 .Net 5 的 API 响应中添加错误或响应代码?

Ruby - 带索引的数组

PHP mcrypt_encrypt/mcrypt_decrypt 问题,返回不同的值

c++ - C++ std::unordered_map 中使用的默认哈希函数是什么?

c# - 等待 Parallel.ForEach

c# - 将 IHttpActionResult 序列化为 JSON 会导致异常

c# - 从 View 中获取当前登录的用户

.net - 如何在 .net 中查找数组的元素类型

.net - swagger.json 链接未显示在 swagger 页面中

c# - 处置与处置( bool )