Почему важно переопределить GetHashCode, если переопределен метод Equals? - PullRequest
1313 голосов
/ 16 декабря 2008

Учитывая следующий класс

public class Foo
{
    public int FooId { get; set; }
    public string FooName { get; set; }

    public override bool Equals(object obj)
    {
        Foo fooItem = obj as Foo;

        return fooItem.FooId == this.FooId;
    }

    public override int GetHashCode()
    {
        // Which is preferred?

        return base.GetHashCode();

        //return this.FooId.GetHashCode();
    }
}

Я переопределил метод Equals, потому что Foo представляет строку для таблицы Foo s. Какой метод является предпочтительным для переопределения GetHashCode?

Почему важно переопределить GetHashCode?

Ответы [ 12 ]

1 голос
/ 07 октября 2013

Насколько я понимаю, оригинальный GetHashCode () возвращает адрес памяти объекта, поэтому его необходимо переопределить, если вы хотите сравнить два разных объекта.

Редакция: Это было неправильно, оригинальный метод GetHashCode () не может гарантировать равенство 2 значений. Хотя равные объекты возвращают один и тот же хэш-код.

0 голосов
/ 14 марта 2014

Ниже использование рефлексии кажется мне лучшим вариантом, учитывая общедоступные свойства, так как при этом вам не нужно беспокоиться о добавлении / удалении свойств (хотя это не очень распространенный сценарий). Я также обнаружил, что это работает лучше (по сравнению с секундомером Diagonistics).

    public int getHashCode()
    {
        PropertyInfo[] theProperties = this.GetType().GetProperties();
        int hash = 31;
        foreach (PropertyInfo info in theProperties)
        {
            if (info != null)
            {
                var value = info.GetValue(this,null);
                if(value != null)
                unchecked
                {
                    hash = 29 * hash ^ value.GetHashCode();
                }
            }
        }
        return hash;  
    }
...