¿Cómo c # determina el código hash para un objeto?

Esta pregunta sale de la discusión sobretuplas.

Comencé a pensar en el código hash que debería tener una tupla. ¿Qué pasa si aceptamos la clase KeyValuePair como una tupla? No anula el método GetHashCode (), por lo que probablemente no estará al tanto de los códigos hash de sus "hijos" ... Por lo tanto, el tiempo de ejecución llamará a Object.GetHashCode (), que no es consciente de estructura de objeto real.

Luego podemos hacer dos instancias de algún tipo de referencia, que en realidad son iguales, debido a la sobrecarga de GetHashCode () y Equals (). Y úsalos como "niños" en tuplas para "engañar" al diccionario.

¡Pero no funciona! ¡El tiempo de ejecución de alguna manera determina la estructura de nuestra tupla y llama al GetHashCode sobrecargado de nuestra clase!

¿Como funciona? ¿Cuál es el análisis realizado por Object.GetHashCode ()?

¿Puede afectar el rendimiento en un mal escenario, cuando usamos algunas claves complicadas? (Probablemente, escenario imposible ... pero igual)

Considere este código como ejemplo:

<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>

Actualizar Creo que he encontrado una explicación para esto como se indica a continuación en mi respuesta. Los principales resultados de la misma son:

Tenga cuidado con sus claves y sus códigos hash :-)Para las claves de diccionario complicadas, debe anular correctamente Equals () y GetHashCode ().

Respuestas a la pregunta(6)

Su respuesta a la pregunta