以类为键的C#词典

时间:2019-07-14 09:32:59

标签: c# class dictionary key

我的问题基本上与Dictionary.ContainsKey return False, but a want True"the given key was not present in the dictionary" error when using a self-defined class as key相反:
我想使用中等大小的类作为字典的键,并且字典必须通过引用而不是值相等来比较键。问题是该类已经实现了int(正在执行值相等-这不是我想要的)。

这里有一个用于复制的小测试班:

Equals()

我尚未实现class CTest { public int m_iValue; public CTest (int i_iValue) { m_iValue = i_iValue; } public override bool Equals (object i_value) { if (ReferenceEquals (null, i_value)) return false; if (ReferenceEquals (this, i_value)) return true; if (i_value.GetType () != GetType ()) return false; return m_iValue == ((CTest)i_value).m_iValue; } } (实际上我已经实现了,但是到目前为止它只返回GetHashCode())。

现在,我用字典创建了一个测试程序,该字典使用此类的实例作为键。我可以将多个相同的实例添加到字典中而不会出现问题,但这仅适用于base.GetHashCode()返回不同的值:

GetHashCode()

哈希值每次都不同,这可能是因为private static void Main () { var oTest1 = new CTest (1); var oTest2 = new CTest (1); bool bEquals = Equals (oTest1, oTest2); // true var dict = new Dictionary<CTest, int> (); dict.Add (oTest1, 1); dict.Add (oTest2, 2); // works var iValue1 = dict[oTest1]; // correctly returns 1 var iValue2 = dict[oTest2]; // correctly returns 2 int iH1 = oTest1.GetHashCode (); // values different on each execution int iH2 = oTest2.GetHashCode (); // values different on each execution, but never equals iH1 } 中的计算使用了一些随机性或一些来自参考句柄的数字(每个对象都不同)。
但是,this answer上的Why is it important to override GetHashCode when Equals method is overridden?表示object.GetHashCode()对于相等的对象必须返回相同的值,因此我添加了

GetHashCode()

在那之后,我无法再将多个相等的对象添加到字典中。

现在,有两个结论:

  1. 如果我再次删除自己的 public override int GetHashCode () { return m_iValue; } ,则哈希值将再次不同,并且可以使用字典。但是有些情况下,可能会意外地为两个相等的对象提供相同的哈希码,这将在运行时导致异常,因此肯定不会找到其原因。由于存在这种风险(很小但不是零),所以我不能使用字典。
  2. 如果我像应该那样正确实现GetHashCode(),则无论如何我都无法使用字典。

仍然可以使用字典吗?

1 个答案:

答案 0 :(得分:0)

就像以前很多次一样,我在写这个问题时有一个解决方案的想法。

您可以在constructor of the dictionary中指定一个GetHashCode()。 .net框架中有一个,但它是IEqualityComparer<TKey>,因此您需要实现自己的:
Is there any kind of "ReferenceComparer" in .NET?

internal sealed