Обзор вопросов по языка програмиированию C# и технологии NET
GetHashCode() — метод System.Object, который возвращает целое число (int), представляющее объект в виде хэш-кода.Dictionary, HashSet, Hashtable).Microsoft рекомендует соблюдать несколько правил:
Согласованность
Equals), то их GetHashCode() должны совпадать.Необязательная уникальность
Стабильность
Equals меняется, хэш-код тоже должен меняться соответствующе, иначе коллекции станут неконсистентными.Пример:
var dict = new Dictionary<Person, string>();
var p1 = new Person("John", 30);
dict[p1] = "Engineer";
p1.Age = 31; // если Age участвует в Equals/GetHashCode
// dict[p1] теперь может не найтись в коллекции
int, double, DateTime) — возвращают хэш, основанный на значении.Object) — возвращают хэш по ссылке объекта, т.е. разные объекты → разные хэши (даже если их содержимое одинаково, пока не переопределён GetHashCode).GetHashCode() так, чтобы одинаковые строки имели одинаковый хэш-код.GetHashCode()Коллекции с хэшированием
Dictionary<TKey, TValue> и HashSet<T> используют хэш-коды для быстрого поиска.Операции Contains, Remove
Equals для подтверждения.LINQ и другие алгоритмы
Distinct, GroupBy).Пример для Dictionary<TKey,TValue>:
GetHashCode() → целое число.hash % buckets.Length.Equals.Важное:
Dictionary, объект может «потеряться».GetHashCode()Equals(), нужно переопределять GetHashCode().class Person:class Person
{
public string Name { get; }
public int Age { get; }
public override bool Equals(object obj) =>
obj is Person p && p.Name == Name && p.Age == Age;
public override int GetHashCode() =>
HashCode.Combine(Name, Age);
}
HashCode.Combine (C# 8.0+) для создания качественного хэша.Обязательность переопределения
Equals, обязательно переопределять GetHashCode.Mutable ключи
Коллизии
Ссылочные типы без переопределения
Стабильность
string (для защиты от DoS атак).HashCode.Combine или System.Collections.StructuralComparisons для массивов/структур.Dictionaryvar dict = new Dictionary<Person, string>();
dict[new Person("Alice", 25)] = "Engineer";
var key = new Person("Alice", 25);
Console.WriteLine(dict.ContainsKey(key)); // true, если Equals и GetHashCode согласованы
HashSetvar set = new HashSet<string>();
set.Add("Hello");
set.Add("Hello"); // не добавит повторно
Distinctvar numbers = new List<int> {1,2,2,3};
var distinct = numbers.Distinct(); // использует GetHashCode + Equals
Что делает GetHashCode()?
Возвращает целое число для хэширования объекта, используемое в хэш-коллекциях.
Что важнее: Equals() или GetHashCode()?
Они связаны: если Equals переопределён, GetHashCode должен быть согласован.
Можно ли использовать изменяемый объект в качестве ключа Dictionary?
Нельзя, если хэш-код зависит от изменяемых полей.
Что такое коллизия? Два разных объекта имеют одинаковый хэш-код.
Почему хэш-код объекта может изменяться между запусками приложения? В .NET Core строки используют случайное смещение для защиты от атак DoS.
Как безопасно реализовать GetHashCode() для нескольких полей?
Использовать HashCode.Combine(field1, field2, ...).
Что произойдёт, если не переопределить GetHashCode() при переопределении Equals()?
Хэш-коллекции могут работать некорректно (не смогут найти объект по ключу).
✨Dvurechensky✨