Переопределение 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;
}
}