Генерация HashCode в конструкторе неизменяемого типа - PullRequest
1 голос
/ 26 мая 2009

У меня есть несколько вопросов о HashCode неизменяемых типов.

  • Могу ли я "предварительно" сгенерировать HashCode неизменяемого типа в конструкторе или есть какая-то причина, чтобы этого не делать?
  • Должен ли я всегда генерировать Hashcode снова, когда вызывается метод GetHashCode ()?

Вот пример класса:

    public class Id  {

        private readonly object _value;

        private readonly int _hash = -1;


        public Id( object value ) {
          _value = value;
          _hash = ( int ) ( 7 * value.GetType().GetHashCode() + 7 + 7 * _value.GetHashCode() );
        }

        public object Value {
          get {
            return _value;
          }
        }

        public override int GetHashCode() {
          return _hash;
        }

        public override bool Equals( object obj ) {
          Id other = obj as Id;

          if ( other == null ) {
            return false;
          }

          return this.GetHashCode() == other.GetHashCode();
        }
        }

Ответы [ 3 ]

8 голосов
/ 26 мая 2009

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

Должен ли я всегда генерировать Hashcode снова, когда вызывается метод GetHashCode ()?

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

Примечание: Вы не должны определять Equals, сравнивая HashCodes - Два разных объекта могут иметь одинаковые HashCodes (хеш-коллизия).

3 голосов
/ 26 мая 2009

Это действительно зависит от варианта использования.

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

Разве хэш не используется часто? Тогда не создавайте его заранее, так как это излишне замедлит программу, вычисляя хеш, который, вероятно, не будет использоваться.

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

1 голос
/ 26 мая 2009

Причина не сгенерирована: она замедляет создание объекта.

Причина постоянной регенерации: вы сохраняете хранилище, необходимое для хранения хеш-кода.

Для записи я бы, вероятно, предварительно вычислил хэш-код и сохранил бы его для неизменяемых объектов , если профилирование не показало, что это дорого, и я не получал доступ к значению очень часто.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...