这个问题来自关于tuples的讨论。
我开始考虑元组应该具有的哈希码。如果我们接受 KeyValuePair 类作为元组呢?它不会覆盖 GetHashCode() 方法,所以它可能不会知道它的“孩子”的哈希码......所以,运行时将调用 Object.GetHashCode(),它不知道实物结构。
然后我们可以创建一些引用类型的两个实例,它们实际上是 Equal,因为重载了 GetHashCode() 和 Equals()。并将它们用作元组中的“孩子”来“欺骗”字典。
但它不起作用!运行时以某种方式计算出我们的元组的结构并调用我们类的重载 GetHashCode!
它是如何工作的?Object.GetHashCode() 做了什么分析?
当我们使用一些复杂的键时,它会在一些糟糕的情况下影响性能吗?(可能,不可能的情况......但仍然)
以这段代码为例:
namespace csharp_tricks
{
class Program
{
class MyClass
{
int keyValue;
int someInfo;
public MyClass(int key, int info)
{
keyValue = key;
someInfo = info;
}
public override bool Equals(object obj)
{
MyClass other = obj as MyClass;
if (other == null) return false;
return keyValue.Equals(other.keyValue);
}
public override int GetHashCode()
{
return keyValue.GetHashCode();
}
}
static void Main(string[] args)
{
Dictionary<object, object> dict = new Dictionary<object, object>();
dict.Add(new KeyValuePair<MyClass,object>(new MyClass(1, 1), 1), 1);
//here we get the exception -- an item with the same key was already added
//but how did it figure out the hash code?
dict.Add(new KeyValuePair<MyClass,object>(new MyClass(1, 2), 1), 1);
return;
}
}
}
更新我想我已经找到了对此的解释,如下所述。它的主要成果是:
- 小心你的密钥和它们的哈希码:-)
- 对于复杂的字典键,您必须正确覆盖 Equals() 和 GetHashCode()。