public class TestHashRace
{
private int cachedHash = 0;
private readonly object value;
public object Value
{
get { return value; }
}
public TestHashRace(object value)
{
this.value = value;
}
public override int GetHashCode()
{
if (cachedHash == 0) {
cachedHash = value.GetHashCode();
}
return cachedHash;
}
//Equals isn't part of the question, but since comments request it, here we go:
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != GetType()) return false;
return Equals((TestHashRace) obj);
}
protected bool Equals(TestHashRace other)
{
return Equals(value, other.value);
}
}
Вот простой тестовый класс.
Гарантируем ли мы, что GetHashCode
всегда будет возвращать одно и то же значение? И если да, может ли кто-нибудь указать на какой-нибудь справочный материал, который дает нам эту гарантию?
Мы не беспокоимся, если он вычисляет хэш-код для нашего значения более одного раза, мы просто хотим быть уверены, что возвращаемое значение всегда будет одинаковым.
Наш класс должен быть неизменным, а поле cachedHash
- изменяемым. Поле не может быть изменчивым по соображениям производительности (вся идея этого вопроса и оптимизации мы здесь ставим под сомнение). Ценность неизменна. И это должно быть потокобезопасным.
Мы можем жить с потенциальным пересчетом хэш-кода, когда он будет равен 0 для некоторых определенных значений. Мы не хотим использовать типы, допускающие значение NULL, или добавлять дополнительные поля по причинам памяти (меньше памяти используется, если мы храним только 1 int), поэтому для решения проблемы хэш-кода должно быть одно поле int.
value
изменится - все, что содержит внешнюю ссылку на него, потенциально может изменить это, сделав ваше кешированное хеш-значение устаревшим. Вам нужен тот же хеш-код или правильный хеш-код? Единственный способ, которым это может работать, - это если объектvalue
может уведомить содержащий класс, если он был изменен таким образом, чтобы изменить его хэш (или вам нужен какой-то способ гарантировать, чтоvalue
не будет изменен извне - сохраните клон или глубокую копию , и т.д). Это должно быть потокобезопасным? Здесь слишком много вопросов ... - person J...   schedule 24.11.2016