Como c # descobre o código hash de um objeto?

Esta questão vem da discussão sobretuplas.

Comecei a pensar sobre o código hash que uma tupla deveria ter. E se aceitarmos a classe KeyValuePair como uma tupla? Ele não substitui o método GetHashCode (), então provavelmente ele não estará ciente dos códigos hash de seus "filhos" ... Assim, o tempo de execução chamará Object.GetHashCode (), que não está ciente do estrutura real do objeto.

Em seguida, podemos fazer duas instâncias de algum tipo de referência, que são, na verdade, Equal, devido ao sobrecarregado GetHashCode () e Equals (). E usá-los como "filhos" em tuplas para "enganar" o dicionário.

Mas isso não funciona! O tempo de execução de alguma forma descobre a estrutura da nossa tupla e chama o GetHashCode sobrecarregado de nossa classe!

Como funciona? Qual é a análise feita por Object.GetHashCode ()?

Isso pode afetar o desempenho em algum cenário ruim, quando usamos algumas chaves complicadas? (provavelmente, cenário impossível ... mas ainda assim)

Considere este código como um exemplo:

<code>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;
        }
    }
}
</code>

Atualizar Acho que encontrei uma explicação para isso, conforme afirmado abaixo na minha resposta. Os principais resultados são:

Tenha cuidado com suas chaves e seus códigos hash :-)Para chaves de dicionário complicadas, você deve substituir Equals () e GetHashCode () corretamente.

questionAnswers(6)

yourAnswerToTheQuestion