Как C # выяснить хеш-код для объекта?
Этот вопрос выходит из обсуждениякортежи.
Я начал думать о хэш-коде, который должен иметь кортеж. Что если мы примем класс KeyValuePair в качестве кортежа? Он не переопределяет метод GetHashCode (), поэтому, вероятно, он не будет знать о хэш-кодах его 'children' ... Таким образом, во время выполнения будет вызываться Object.GetHashCode (), который не является знать о реальной структуре объекта.
Затем мы можем сделать два экземпляра некоторого ссылочного типа, которые на самом деле равны, из-за перегруженных GetHashCode () и Equals (). И использовать их как «детей» в кортежах для «обмана» словарь.
Но это не работает! Во время выполнения каким-то образом выясняется структура нашего кортежа и вызывается перегруженный GetHashCode нашего класса!
Как это работает? Что такое анализ, выполненный Object.GetHashCode ()?
Может ли это повлиять на производительность в каком-то плохом сценарии, когда мы используем сложные ключи? (возможно, сценарий невозможен ... но все же)
Рассмотрим этот код в качестве примера:
<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>
Update Я думаю, что нашел объяснение этому, как указано ниже в моем ответе. Основными результатами этого являются:
Be careful with your keys and their hash codes :-) For complicated dictionary keys you must override Equals() and GetHashCode() correctly.