Переопределение GetHashCode(): создание хэш по User.Surname и User.Name

193
21 января 2018, 01:18

КОД

Есть класс c переопределенным методом Equals()

/// <summary>
/// Описание пользователя
/// </summary>
/// <remarks>Объект данного класса также является сущностью базы данных</remarks>
public class User
{
    public string Surname { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
    public override bool Equals(object obj)
    {
        if (!(obj is User secondUser))
            return false;
        return this.Surname.Equals(secondUser.Surname) && this.Name.Equals(secondUser.Name);
    }
    public override int GetHashCode()
    {
        //?
    }
}

ВОПРОС

Не знаю как переопределить метод GetHashCode() согласно моему условию уникальности - достаточно, чтобы совпадало фамилия и имя.

МОИ ПОИСКИ

Из всего поиска хочется выделить вот эти две статьи

  1. CA2218: переопределяйте GetHashCode при переопределении Equals. Хоть я и не новичок в мире программирования, но термин поразрядная операция ^ меня вводит просто в ступор. Не понимаю, что это такое. Думал это больше из мира Си.
  2. GetHashCode — вычисление хэш. Эта статься больше ввела меня в курс дела, но тут у автора в качестве полей типы значимые и поэтому полегче.

Хотел сказать, что и эти две статьи не помогли мне.

Answer 1

Вычисление хэшкода должно быть быстрым (быстрее полного сравнения), и не должно плодить мусор.

Варианты типа (Name+Surname).GetHashCode()

  1. Создадут временную строку
  2. Посчитают по ней хэш
  3. Выбросят временную строку в мусор

Причем это произойдет для обоих сравниваемых объектов. Такое вычисление хэшкода - дороже, чем прямое сравнение объектов.

Судя по комментарию

/// <remarks>Объект данного класса также является сущностью базы данных</remarks>

у вас этот класс будет лежать в базе данных. И у него скорее всего будет поле UserID. Вот и реализуйте GetHashCode как

public override int GetHashCode()
{
    return this.UserID.GetHashCode(); 
}

или даже

public override int GetHashCode()
{
    return this.UserID; 
}

И, соответственно, дописать сравнение по UserID в Equals - пользователи с разным UserID не должны считаться Equal;

Если UserID нет, то используйте в качестве хэшкода комбинацию хэшкодов неизменяемых полей (только тех, которые используются в Equals):

public override int GetHashCode()
{
    return Name.GetHashCode() * 13 + Surname.GetHashCode();
}

Ну или просто возвращайте хэш какого-то достаточно уникального поля, если нет альтернатив:

public override int GetHashCode()
{
    return Surname.GetHashCode();
}
READ ALSO
Отследить KeyPress из класса наследника TabPage

Отследить KeyPress из класса наследника TabPage

Создал класс у которого родитель TabPage (проект winforms), как мне отслеживать нажатие клавиш из класса?

213
Работа с safeframe

Работа с safeframe

Использую эту либу для создания safeframehttps://github

261
Статус 500, при PUT

Статус 500, при PUT

Здравствуйте, столкнулся с проблемойТ

353