我的问题基本上与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()
在那之后,我无法再将多个相等的对象添加到字典中。
现在,有两个结论:
public override int GetHashCode ()
{
return m_iValue;
}
,则哈希值将再次不同,并且可以使用字典。但是有些情况下,可能会意外地为两个相等的对象提供相同的哈希码,这将在运行时导致异常,因此肯定不会找到其原因。由于存在这种风险(很小但不是零),所以我不能使用字典。 GetHashCode()
,则无论如何我都无法使用字典。仍然可以使用字典吗?
答案 0 :(得分:0)
就像以前很多次一样,我在写这个问题时有一个解决方案的想法。
您可以在constructor of the dictionary中指定一个GetHashCode()
。 .net框架中有一个,但它是IEqualityComparer<TKey>
,因此您需要实现自己的:
Is there any kind of "ReferenceComparer" in .NET?
internal sealed