C# 同一程序集中类型的System.Type对象的哈希代码是否保证唯一?

C# 同一程序集中类型的System.Type对象的哈希代码是否保证唯一?,c#,.net,dictionary,hash,C#,.net,Dictionary,Hash,澄清编辑:字典中的键是系统的实际实例。键入。更具体地说,每个值都以其类型作为键存储 根据Visual Studio 2017 performance profiler的说法,在我的程序的特定部分中,字典的使用占用了大量CPU时间 将dictionary的类型更改为dictionary,而不是直接传递type对象,而是传递type.GetHashCode()似乎要快20%-25% 如果两个类型具有相同的哈希代码,则上述优化将导致一个严重的错误,但在我看来,类型可以具有唯一的哈希代码似乎是合理的,至

澄清编辑:字典中的键是
系统的实际实例。键入
。更具体地说,每个值都以其类型作为键存储

根据Visual Studio 2017 performance profiler的说法,在我的程序的特定部分中,字典的使用占用了大量CPU时间

将dictionary的类型更改为
dictionary
,而不是直接传递type对象,而是传递
type.GetHashCode()
似乎要快20%-25%

如果两个类型具有相同的哈希代码,则上述优化将导致一个严重的错误,但在我看来,类型可以具有唯一的哈希代码似乎是合理的,至少当涉及到来自相同程序集的类型时是这样的,本词典中使用的所有类型都是这样的


可能相关信息-根据程序集中可能类型的数量远远小于
系统表示的值的数量。Int32

哈希代码对于不同的值永远不会被认为是唯一的,因此您不应该像现在这样使用它。 但是,相同的值应生成相同的哈希代码

这也在以下文件中说明:

两个相等的对象返回相等的哈希代码。但是,情况并非如此:相等的哈希代码并不意味着对象相等,因为不同(不相等)的对象可以具有相同的哈希代码

再进一步说:

不要使用哈希代码作为键从键控集合检索对象

因此,不同类型的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!");
Dictionary s=newdictionary();
var types=typeof(int).Assembly.GetTypes();
WriteLine($“检查{types.Length}类型…”);
foreach(typeof中的var t(-在此处放置来自该程序集的类型-).assembly.GetTypes()
{
if(s.ContainsKey(t.GetHashCode()))
{
WriteLine($“{t.Name}与{s[t.GetHashCode()]}具有相同的哈希代码);
}
其他的
{
s、 添加(t.GetHashCode(),t.Name);
}
}
控制台。WriteLine(“完成!”);

但是,即使上面的测试会得出没有冲突的结论,我也不会这样做,因为GetHashCode的实现会随着时间的推移而改变,这意味着将来可能会发生冲突。

hashcode不是唯一的。相反,它用于基于哈希的集合,例如
字典
,以限制可能的歧义数量。hashc ode只不过是一个索引,因此不必在整个集合中搜索匹配项,只需考虑共享一个公共值(哈希代码)的几个项

事实上,您甚至可以有一个哈希实现,它总是为每个项返回相同的数字。然而,这将导致O(n)在字典中查找一个键,因为每个键都必须进行比较

无论如何,你不应该为了获得可维护性和可理解性而进行微优化。相反,您应该使用一些能够完成工作且易于理解的数据结构。

否。文档不提供任何保证,并说明:

哈希代码用于在基于哈希表的集合中高效插入和查找。哈希代码不是永久值。因此:

  • 不要使用哈希代码作为键从键控集合检索对象
因为相等的散列码对于两个对象相等是必要的,但还不够


如果您想知道
Type.GetHashCode()
是否遵循了更严格的定义,那么它没有提到这样的更改,因此仍然不能保证唯一性。也没有显示任何对此保证的尝试。

散列码不用于标识,也不保证是唯一的。它们只是足够唯一以便快速找到。您甚至可以编写一个哈希代码,该代码始终返回
1
。我认为,当您覆盖保证此功能正常运行所需的所有内容时,它将消耗您的储蓄,然后再消耗一些。这是一个简单的概率问题,即使是最低概率也会时不时地发生,也许就在你下一次尝试它的时候。很明显,创建一组类并确保它们具有唯一的哈希代码是可能的,这就是我在这里要问的。我不会依赖于此:)@,也可以让类确保它们没有唯一的哈希代码。我们怎么知道你不是在说这些?您的问题中没有任何东西可以让我们断定您的类实例具有唯一的哈希代码。@如果您需要的话,您完全可以为程序集中的每个类型重写
GetHashCode
,并提供适当的唯一值。事实上,这就是创建简单类型时必须要做的事情。这是一个文档可以通过简单搜索为您解答的问题。我不是问哈希代码一般来说是否唯一,只是问它们对于类型(或至少是同一程序集中的类型)是唯一的。如果对象数量相对较少,显然可以实现
GetHashCode
方法来返回唯一的哈希代码。我只关心
System.Type
GetHashCode
的实现。如前所述,该实现(及其文档)不保证这一点。