来自同一程序集的System.Type类型对象的哈希码是否保证唯一?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了来自同一程序集的System.Type类型对象的哈希码是否保证唯一?相关的知识,希望对你有一定的参考价值。
澄清编辑:字典中的键是System.Type
的实际实例。更具体地说,每个值都以其类型作为键存储。
在我的程序的特定部分中,根据Visual Studio 2017性能分析器,Dictionary<System.Type, SomeThing>
的使用占用了大量的CPU时间。
将字典类型更改为Dictionary<int, SomeThing>
而不是直接传递类型对象我通过type.GetHashCode()
似乎要快20%-25%。
如果两种类型具有相同的哈希码,则上述优化将导致一个讨厌的错误,但似乎我认为类型可以具有唯一的哈希码,至少在涉及来自相同汇编的类型时 - 所有类型都使用这本词典是。
可能相关的信息 - 根据this answer,装配中可能类型的数量远小于System.Int32
所代表的值的数量。
不。文件on object.GetHashCode()
不作任何保证,并声明:
哈希码旨在用于在基于哈希表的集合中进行有效插入和查找。哈希码不是永久值。为此原因:
...
- 不要使用哈希代码作为从密钥集合中检索对象的密钥。
因为相同的哈希码是必要的,但不足以使两个对象相等。
如果你想知道Type.GetHashCode()
是否遵循更严格的定义,its documentation没有提到这样的改变,所以它仍然不能保证唯一性。 reference source也没有表现出任何提出这种保证的企图。
对于不同的值,哈希代码永远不会保证是唯一的,因此您不应该像使用它一样使用它。但是,相同的值应该生成相同的哈希码。
这也在MSDN中说明:
两个相等的对象返回相等的哈希码。但是,相反的情况并非如此:相等的哈希码并不意味着对象相等,因为不同(不相等)的对象可以具有相同的哈希码。
并进一步:
不要使用哈希代码作为从密钥集合中检索对象的密钥。
因此,我也不会依赖于不同类型的GetHashCode是唯一的,但至少,你可以验证它:
Dictionary<int, string> s = new Dictionary<int, string>();
var types = typeof(int).Assembly.GetTypes();
Console.WriteLine($"Inspecting {types.Length} types...");
foreach (var t in typeof(-put a type from that assembly here-).Assembly.GetTypes())
{
if (s.ContainsKey(t.GetHashCode()))
{
Console.WriteLine($"{t.Name} has the same hashcode as {s[t.GetHashCode()]}");
}
else
{
s.Add(t.GetHashCode(), t.Name);
}
}
Console.WriteLine("done!");
但即使上面的测试得出的结论是没有冲突,我也不会这样做,因为GetHashCode的实现可能会随着时间而改变,这意味着将来可能会发生冲突。
哈希码不是唯一的。相反,它用于基于散列的集合,例如Dictionary
,以限制可能的歧义的数量。 hashc-ode只是一个索引,因此不必搜索整个集合中的匹配项,而只需要考虑共享一个共同值的几个项 - 哈希码。
实际上你甚至可以有一个哈希实现,它总是为每个项返回相同的数字。然而,这将导致O(n)在您的字典中查找密钥,因为必须比较每个密钥。
无论如何,你不应该努力进行微观优化,以获得一些纳秒来换取可维护性和可理解性。您应该使用一些数据结构来完成工作并且易于理解。
以上是关于来自同一程序集的System.Type类型对象的哈希码是否保证唯一?的主要内容,如果未能解决你的问题,请参考以下文章
来自程序集的类型是使用旧版本的 blend sdk 构建的,并且在 Windows Presentation Foundation 4 项目中不受支持