这个问题来自于讨论tuples https://stackoverflow.com/questions/101825/whats-the-best-way-of-using-a-pair-triple-etc-of-values-as-one-value-in-c.
我开始思考元组应该具有的哈希码。
如果我们接受 KeyValuePair 类作为元组怎么办?它不会覆盖 GetHashCode() 方法,因此可能不会知道它的“子级”的哈希码...因此,运行时将调用 Object.GetHashCode(),而它不知道真实的物体结构。
然后我们可以创建某个引用类型的两个实例,由于重载了 GetHashCode() 和 Equals(),它们实际上是 Equal。并将它们用作元组中的“子项”来“欺骗”字典。
但这不起作用!运行时以某种方式找出元组的结构并调用我们类的重载 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;
}
}
}
Update我想我已经在我的回答中找到了对此的解释。其主要成果有:
- 请小心您的密钥及其哈希码:-)
- 对于复杂的字典键,您必须正确重写 Equals() 和 GetHashCode()。