我有一个项目,我正在广泛使用通用的cdictionary。我需要组合键,所以我一直使用tuples作为键。在某种程度上,我想知道使用缓存哈希代码的自定义类是否有益:
public class CompositeKey<T1, T2> : Tuple<T1, T2>
{
private readonly int _hashCode;
public CompositeKey(T1 t1, T2 t2) : base(t1, t2)
{
_hashCode = base.GetHashCode();
}
public new int GetHashCode()
{
return _hashCode;
}
}
我使用了
new
而不是override
,因为我认为这对测试没有影响,因为我是使用具体类型定义字典的:var dict = new Dictionary<CompositeKey<string, int>, int>();
然而,我注意到我的自定义
GetHashCode
方法根本没有被调用。当我将new
更改为override
时,它按预期被调用。有人能解释为什么不调用隐藏的
GetHashCode
方法吗?如果我把字典定义成这样的话,我会预料到这种行为var dict = new Dictionary<Tuple<string, int>, int>();
但如果像我的示例中那样显式地指定
CompositeKey
类型,则不会。我知道隐藏
GetHashCode
方法可能不是个好主意。 最佳答案
有人能解释为什么不调用隐藏的gethashcode方法吗?
如果我把字典定义为
这
要调用CompositeKey.GetHashCode
方法,必须在编译时将CompositeKey
实例的引用键入CompositeKey
。
但是Dictionary<TKey,TValue>
的代码库并不知道您的CompositeKey
类(显然)。它所知道的是TKey
(泛型类型参数),它与没有任何约束的System.Object
等价。因为除了在T
中声明的方法之外,您不能调用任何System.Object
的方法,而没有约束。
所以,dictionary最终调用的Object.GetHashCode
在类中不会被重写,因此它不会被调用。