为什么C#字典不会调用隐藏的GetHashCode方法

fkn*_*knx 7 c# dictionary

我有一个项目,我广泛使用通用的C#字典.我需要复合键,所以我一直使用元组作为键.在某些时候,我想知道使用缓存哈希码的自定义类是否有益:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

我使用new而不是override因为我认为它对这个测试没有任何影响,因为我使用具体类型定义字典:

var dict = new Dictionary<CompositeKey<string, int>, int>();
Run Code Online (Sandbox Code Playgroud)

但是,我注意到我的自定义GetHashCode方法根本没有被调用.当我改变它时,按预期调用newoverride它.

有人可以解释为什么GetHashCode不调用隐藏方法?如果我像这样定义字典,我会期待这种行为

var dict = new Dictionary<Tuple<string, int>, int>();
Run Code Online (Sandbox Code Playgroud)

但如果我CompositeKey在我的例子中明确指定了类型,则不行.

PS我知道隐藏这个GetHashCode方法可能不是一个好主意.

Sri*_*vel 10

有人可以解释为什么不调用隐藏的GetHashCode方法吗?如果我像这样定义字典,我会期待这种行为

为了能够调用CompositeKey.GetHashCode方法,必须在编译时具有CompositeKeytyped 实例的引用CompositeKey.

但是代码库Dictionary<TKey,TValue>并不知道你的CompositeKey类(显然).它只知道TKey(泛型类型参数),它与System.Object没有任何约束的情况相同.因为TSystem.Object没有约束的情况下,您无法调用任何其他方法.

因此,字典最终会调用Object.GetHashCode哪个不会在您的类中被覆盖 - 因此它不会被调用.