.NET Dictionary <T,T>用什么来散列引用?

Pol*_*878 2 .net c# hash

所以我想使用引用类型作为.NET Dictionary的键...

例:

class MyObj
{
    private int mID;
    public MyObj(int id)
    {
        this.mID = id;
    }
}

// whatever code here
static void Main(string[] args)
{
    Dictionary<MyObj, string> dictionary = new Dictionary<MyObj, string>();
}
Run Code Online (Sandbox Code Playgroud)

我的问题是,如何为自定义对象生成哈希(即不是int,string,bool等)?我问,因为在我需要再次在Dictionary中查找内容之前,我用作键的对象可能会发生变化.如果哈希是从对象的地址生成的,那么我可能很好......但是如果它是从对象的成员变量的某种组合生成的那么我就麻烦了.

编辑:

我原本应该明确表示我并不关心在这种情况下对象的相等性......我只是在寻找快速查找(我想在没有更改代码的情况下进行1-1关联涉及的课程).

谢谢

Jon*_*eet 7

GetHashCode/Equals的默认实现基本上处理身份.你总是会从同一个对象中获得相同的哈希值,并且它可能与其他对象不同(非常高的概率!).

换句话说,如果你只想要参考标识,那你就没事了.如果你想使用字典来处理键作为(即使用对象内的数据,而不仅仅是对象引用本身,以确定相等的概念)那么改变任何相等敏感数据是一个坏主意将其添加到词典后,在键中.

MSDN文档object.GetHashCode有点过于可怕 - 基本上你不应该将它用于持久性哈希(即在进程调用之间保存),但它对于同一个对象是一致的,这对于它是一个有效的哈希是必需的一本字典.虽然它不能保证是唯一的,但我认为你不会遇到足够的集合来引起问题.


Jar*_*Par 5

使用的哈希是对象上.GetHashcode方法的返回值。默认情况下,这实质上是代表参考的值。它不能保证对象唯一,并且实际上可能在很多情况下都不是唯一的。但是,即使您对其进行了更改,特定引用的值也不会在对象的生存期内改变。因此,对于此特定示例,您将可以。

但是,总的来说,使用不可变的对象作为Dictionary的键是一个非常糟糕的主意。陷入陷阱(覆盖对象上的Equals和GetHashcode)并破坏以前将类型用作字典中键的代码非常容易。

  • @ Polaris878:通常,您想按*值*而不是*引用*来比较键,因此您将覆盖Equals / GetHashCode。到那时,对键进行更改将更改其哈希值,这会使字典更加混乱。 (2认同)