我知道不建议使用“可变”对象(其 GetHashCode() 方法在用作Dictionary中的键时可以返回不同结果的对象)。
以下是我对实现为哈希表的字典如何工作的理解:
例如,当我添加新密钥时dict.Add(m1, "initially here was m1 object");
,dict
计算m1
使用该GetHashCode()
方法的哈希码。然后它进行一些内部计算,最后将这个对象放入其内部数组的某个位置。
dict[m1]
例如,当我使用键索引获取值时,dict
再次计算哈希码。然后它进行一些内部计算,它给了我一个位于其内部数组内部计算位置的对象。
但我认为有一个我找不到的错误。
所以让我们假设我有这个代码:
class MutableObject
{
Int32 m_value;
public MutableObject(Int32 value)
{
m_value = value;
}
public void Mutate(Int32 value)
{
m_value = value;
}
public override int GetHashCode()
{
return m_value;
}
}
static void Main(string[] args)
{
MutableObject m1 = new MutableObject(1);
MutableObject m2 = new MutableObject(2);
var dict = new Dictionary<MutableObject, String>();
dict.Add(m1, "initially here was m1 object");
dict.Add(m2, "initially here was m2 object");
Console.WriteLine("Before mutation:");
Console.WriteLine("dict[m1] = " + dict[m1]);
Console.WriteLine("dict[m2] = " + dict[m2]);
m1.Mutate(2);
m2.Mutate(1);
Console.WriteLine("After mutation:");
Console.WriteLine("dict[m1] = " + dict[m1]);
Console.WriteLine("dict[m2] = " + dict[m2]);
Console.ReadKey(true);
}
当我调用Mutate
方法时,键被交换。所以我认为它会给出交换的结果。但实际上这一行:Console.WriteLine("dict[m1] = " + dict[m1]);
抛出 KeyNotFoundException,我不明白为什么。显然我在这里遗漏了一些东西......