Переопределение GetHashCode

Как вы знаете, GetHashCode возвращает полууникальное значение, которое можно использовать для идентификации экземпляра объекта в коллекции. В качестве хорошей практики рекомендуется переопределить этот метод и реализовать свой собственный.

Мой вопрос - вы переопределите этот метод при работе с пользовательскими объектами? Если да, то какой алгоритм вы используете для генерации уникального идентификатора?

Я думал о создании GUID, а затем получить целочисленные данные из этого идентификатора.

6 ответов

Решение

Когда вы переопределяете GetHashCode() вам также нужно переопределить Equals(), operator== а также operator!=, И будьте очень осторожны, чтобы соответствовать всем требованиям для этих методов.

Руководство здесь на MSDN. Наиболее важная цитата:

Не стоит переопределять оператор == в неизменяемых типах.

Если вы используете resharper, он может сгенерировать для вас GetHashCode(), Equals и тела операторов.

Войдите в это меню, нажав Alt+Insert.

http://www.jetbrains.com/resharper/webhelp/Code_Generation__Equality_Members.html

Обычно я переопределяю методы хеширования и проверки на равенство для классов данных (т. Е. Классов, в которых семантика значений имеет смысл). Посмотрите на этот вопрос для общей реализации. Если вы переопределите хэш-код, то переопределите равно. Использование GUID - довольно ужасная идея, потому что вы хотите, чтобы два объекта, которые были разными экземплярами, но имели одно и то же значение, имели одинаковый хэш-код, а для equals возвращалось значение true.

В моем личном использовании я переопределяю только при переопределении метода равно. Обычно я делаю это для объектов, о которых я знаю, что мог бы выполнить запрос LINQ to Objects или выполнить какую-либо другую операцию сравнения.

Обычно я возвращаю значение первичного ключа, если, скажем, объект LINQ to SQL или объект DTO. Что бы вы ни возвращали, если вы не храните значение локально, это может привести к неожиданному результату.

НТН.

Вам нужно только переопределить GetHashCode, если вы переопределяете Equals. GetHashCode по умолчанию реализуется средой выполнения аналогично тому, как вы хотели это сделать - у каждого объекта есть скрытое поле, назначенное средой выполнения.

Как переопределить GetHashCode

На самом деле ваша IDE должна сделать это за вас - когда вы набираете "переопределить GetHashCode", IDE должна генерировать этот шаблонный код. Visual Studio не делает этого, но делает SharpDevelop.

Обычно я использую агрегированный GetHashCode из свойств компонента класса. Например

public class Test
{
  public string Text { get; set; }
  public int Age { get; set; }

  public override GetHashCode()
  {
    int result = 
      string.IsNullOrEmpty(Text) ? 0 : Text.GetHashCode()
      + Age.GetHashCode();

    return result;
  }
}
Другие вопросы по тегам