Esta pregunta sale del debate en tuples.¿Cómo calcula C# el código hash de un objeto?
Empecé a pensar en el código hash que debe tener una tupla. ¿Qué sucede si aceptamos la clase KeyValuePair como una tupla? No anula el método GetHashCode(), por lo que probablemente no tenga en cuenta los códigos hash de sus "hijos" ... Por lo tanto, el tiempo de ejecución llamará a Object.GetHashCode(), que no tiene conocimiento del estructura real del objeto
Luego podemos hacer dos instancias de algún tipo de referencia, que en realidad son iguales, debido a la sobrecarga GetHashCode() e Igual(). Y úselos como "niños" en tuplas para "engañar" al diccionario.
¡Pero no funciona! ¡El tiempo de ejecución de alguna manera descubre la estructura de nuestra tupla y llama al sobrecargado GetHashCode de nuestra clase!
¿Cómo funciona? ¿Cuál es el análisis realizado por Object.GetHashCode()?
¿Puede afectar el rendimiento en algunos escenarios malos, cuando usamos algunas teclas complicadas? (Probablemente, escenario imposible ... pero aún así)
consideran este código como un ejemplo:
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;
}
}
}
actualización 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:
- tener cuidado con sus claves y sus códigos hash :-)
- Para complicadas claves del diccionario debe invalidar Iguales() y GetHashCode() correctamente.
Esta explicación contradice con el ejemplo de código en la pregunta . –