Программирование игр, создание игрового движка, OpenGL, DirectX, физика, форум
GameDev.ru / Программирование / Форум / [C#] Как лучше переопределить GetHashCode?

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

smartxpПостоялецwww7 июня 201821:01#0
Как лучше переопределить 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
        );
    }
}
MrShoorУчастникwww8 июня 20184:13#1
smartxp
Считать хеш от полей и комбинировать? По аналогии с hash_combine из буста:
+ Показать

?
smartxpПостоялецwww8 июня 20189:57#2
MrShoor
> Считать хеш от полей и комбинировать?
Если, имеется ввиду, типа:
return (iValue1.GetHashCode() ^ iValue2.GetHashCode() ^...)
ну или любая другая формула, то дело в том, что поля-то не readonly и могут быть изменены в процессе, про данную проблему с HashSet хорошо тут написано.
Вот я и думаю, как лучше, пока склоняюсь к варианту:
return 1
По идее, если коллекции будут не большими, то на производительность не сильно скажется.
Sbtrn. DevilПостоялецwww8 июня 201812:15#3
smartxp
> поля-то не readonly и могут быть изменены в процессе,
Хэшкод намекает, что данный объект будет использоваться в качестве мапного ключа. Иметь в ключе поля, которые влияют на его сравнение и при этом мутабельные - идея в корне неправильная.
alexzzzzПостоялецwww8 июня 201823:33#5
Решарпер предлагает
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.

MrShoorУчастникwww9 июня 20180:05#6
smartxp
> про данную проблему с HashSet хорошо тут написано.
Там хорошо написано в первом же комментарии к статье.
smartxpПостоялецwww9 июня 20188:22#7
MrShoor
> smartxp
> > про данную проблему с HashSet хорошо тут написано.
> Там хорошо написано в первом же комментарии к статье.
Так-то оно так, но никогда не знаешь, какой балбес и как воспользуется твоим классом.

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

MrShoorУчастникwww9 июня 20188:30#8
smartxp
> Так-то оно так, но никогда не знаешь, какой балбес и как воспользуется твоим
> классом.
Я надеюсь ты знаешь, чем чревата хешфункция return 1 ?
smartxpПостоялецwww9 июня 20188:34#9
MrShoor
> Я надеюсь ты знаешь, чем чревата хешфункция return 1 ?
замедлением работы из-за постоянного обращения к Equals или еще чем-то?
MrShoorУчастникwww9 июня 20188:37#10
smartxp
> замедлением работы из-за постоянного обращения к Equals или еще чем-то?
Замедлением работы из-за постоянных коллизий, которые конечно же тоже приводят к Equals.
То есть если ты сделаешь HashSet из таких вот result 1, то твой HashSet будет работать медленнее, чем просто поиск по List-у из этих структур.
smartxpПостоялецwww9 июня 20188:48#11
MrShoor
> То есть если ты сделаешь HashSet из таких вот result 1, то твой HashSet будет
> работать медленнее, чем просто поиск по List-у из этих структур.
ясно
EugeneУчастникwww9 июня 201812:20#12
smartxp
> Так-то оно так, но никогда не знаешь, какой балбес и как воспользуется твоим
> классом.
У нас в крестах намного проще. Если человек так сильно хочет выстрелить себе в ногу, он стреляет, и никто ему не мешает.
ZefickПостоялецwww9 июня 201813:46#13
KolyaL
> https://stackoverflow.com/questions/263400/what-is-the-best-algor…hashcode?rq=1
  IMHO лучший ответ оттуда:
new { PropA, PropB, PropC, PropD }.GetHashCode();
smartxpПостоялецwww10 июня 201818:25#14
Zefick
>   IMHO лучший ответ оттуда:
> new { PropA, PropB, PropC, PropD }.GetHashCode();
Любопытно, как в анонимных типах реализован GetHashCode?

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

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

Правка: 10 июня 2018 20:56

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

2001—2018 © GameDev.ru — Разработка игр