Войти
ПрограммированиеФорумОбщее

[C#] Как лучше переопределить GetHashCode?

#0
21:01, 7 июня 2018

Как лучше переопределить GetHashCode для данного класса?

public class SomeClass : System.IEquatable<SomeClass>
{
    public enum SomeTypeEnum
    {
        type1 = 0,
        type2 = 1
    }

    public int iValue1;
    public int iValue2;
    public SomeTypeEnum type;
    public decimal dValue;
    public string str;

    public override bool Equals(object obj)
    {
        return Equals(obj as SomeClass);
    }

    public bool Equals(SomeClass other)
    {
        return
        (
            other != null &&
            iValue1 == other.iValue1 &&
            iValue2 == other.iValue2 &&
            type == other.type &&
            dValue == other.dValue &&
            str == other.str
        );
    }
}


#1
4:13, 8 июня 2018

smartxp
Считать хеш от полей и комбинировать? По аналогии с hash_combine из буста:

+ Показать

?
#2
9:57, 8 июня 2018

MrShoor
> Считать хеш от полей и комбинировать?
Если, имеется ввиду, типа:

return (iValue1.GetHashCode() ^ iValue2.GetHashCode() ^...)
ну или любая другая формула, то дело в том, что поля-то не readonly и могут быть изменены в процессе, про данную проблему с HashSet хорошо тут написано.
Вот я и думаю, как лучше, пока склоняюсь к варианту:
return 1
По идее, если коллекции будут не большими, то на производительность не сильно скажется.
#3
12:15, 8 июня 2018

smartxp
> поля-то не readonly и могут быть изменены в процессе,
Хэшкод намекает, что данный объект будет использоваться в качестве мапного ключа. Иметь в ключе поля, которые влияют на его сравнение и при этом мутабельные - идея в корне неправильная.

#4
16:36, 8 июня 2018

https://stackoverflow.com/questions/263400/what-is-the-best-algor… hashcode?rq=1

#5
23:33, 8 июня 2018

Решарпер предлагает

public override int GetHashCode()
{
  unchecked
  {
    int hashCode = iValue1;
    hashCode = (hashCode * 397) ^ iValue2;
    hashCode = (hashCode * 397) ^ (int)type;
    hashCode = (hashCode * 397) ^ dValue.GetHashCode();
    hashCode = (hashCode * 397) ^ (str != null ? str.GetHashCode() : 0);
    return hashCode;
  }
}

ругаясь при этом, что поля не readonly.

#6
0:05, 9 июня 2018

smartxp
> про данную проблему с HashSet хорошо тут написано.
Там хорошо написано в первом же комментарии к статье.

#7
8:22, 9 июня 2018

MrShoor
> smartxp
> > про данную проблему с HashSet хорошо тут написано.
> Там хорошо написано в первом же комментарии к статье.
Так-то оно так, но никогда не знаешь, какой балбес и как воспользуется твоим классом.

Хм... можно сделать все поля readonly, что бы заставить... хотя во всех классах делать все поля readonly... может, только ключевые, хотя и это снизит удобство работы с классом... надо подумать.

#8
8:30, 9 июня 2018

smartxp
> Так-то оно так, но никогда не знаешь, какой балбес и как воспользуется твоим
> классом.
Я надеюсь ты знаешь, чем чревата хешфункция return 1 ?

#9
8:34, 9 июня 2018

MrShoor
> Я надеюсь ты знаешь, чем чревата хешфункция return 1 ?
замедлением работы из-за постоянного обращения к Equals или еще чем-то?

#10
8:37, 9 июня 2018

smartxp
> замедлением работы из-за постоянного обращения к Equals или еще чем-то?
Замедлением работы из-за постоянных коллизий, которые конечно же тоже приводят к Equals.
То есть если ты сделаешь HashSet из таких вот result 1, то твой HashSet будет работать медленнее, чем просто поиск по List-у из этих структур.

#11
8:48, 9 июня 2018

MrShoor
> То есть если ты сделаешь HashSet из таких вот result 1, то твой HashSet будет
> работать медленнее, чем просто поиск по List-у из этих структур.
ясно

#12
12:20, 9 июня 2018

smartxp
> Так-то оно так, но никогда не знаешь, какой балбес и как воспользуется твоим
> классом.
У нас в крестах намного проще. Если человек так сильно хочет выстрелить себе в ногу, он стреляет, и никто ему не мешает.

#13
13:46, 9 июня 2018

KolyaL
> https://stackoverflow.com/questions/263400/what-is-the-best-algor…hashcode?rq=1
  IMHO лучший ответ оттуда:

new { PropA, PropB, PropC, PropD }.GetHashCode();
#14
(Правка: 20:56) 18:25, 10 июня 2018

Zefick
>   IMHO лучший ответ оттуда:
> new { PropA, PropB, PropC, PropD }.GetHashCode();
Любопытно, как в анонимных типах реализован GetHashCode?

Замерил производительность, этот способ хуже, чем

return 1
Сильнее нагружает систему и дольше выполняется.

ПрограммированиеФорумОбщее