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 для некоторых значений. Мы не хотим использовать типы с нулевым значением или добавлять дополнительные поля по соображениям памяти (меньше памяти используется, если мы сохраняем только 1 int), поэтому для обработки проблемы hashcode должно быть одно int-поле.
Непонятно, что вы пытаетесь сделать здесь. У вас нет возможности узнать, когда изменится значение «value» - все, что имеет внешнюю ссылку, потенциально может изменить его, что приведет к сохранению вашего значения кэшированного хэша. Вы хотите «тот же» хэш-код или хотите «правильный» хэш? Единственный способ, которым это может работать, - это если объект 'value' может уведомить содержащийся класс, если был изменен таким образом, который изменит его хэш (или вам нужно каким-то образом гарантировать, что' value' не будет изменено извне - сохраните клон или глубокая копия и т. д.). Должно ли это быть потокобезопасным? Слишком много вопросов здесь ... –
Преодоление GetHashCode без переопределения Равенство приведет к ошибкам. Вы должны показать равную реализацию слишком –
@J ... отредактированный вопрос для удовлетворения ваших требований –