Главная » C# » Реализация метода EqualsQ в Visual C# (Sharp)

0

Исходный код для реализации метода Equals ()  выглядит таким образом:

public override bool Equals(object obj) { if (obj is HashcodeExample) {

return obj.GetHashCode() == this.GetHashCode();

}

else {

return false;

}

}

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

String si = "Hello"; String s2 = "World";

int xl = 17 * 17 + si.GetHashCode(); int x2 = 17 * 17 + s2.GetHashCode();

HashCodeExample hi = new HashCodeExample(x2 * 37, si); HashCodeExample h2 = new HashCodeExample(xl * 37, s2);

Hashtable ht = new Hashtable(); ht.Add(hl, null);

ht.Add(h2, null);

Как можно видеть, два объекта с полностью разными состояниями выдают одиновые значения хэш-кода, что вызывает исключение, т. к. метод Equals () реализан неправильно. В реализации Hashtable, когда имеется коллизия добавленного объекта с другим, уже существующим объектом, выполняется проверка на раветво объектов. В случае положительного результата проверки генерируется искление, т. к. Hashtable не разрешает добавлять объект с таким же состоянием, как и состояние другого объекта.

Решением  будет  не  исправлять  метод  GetHashCode (),  но  модифицировать  метод

Equals():

public override bool Equals(object obj) { if (obj is HashCodeExampleWorking) {

i f (obj.GetHashCode() != thi s.GetHashCode()) return false;

‘// Нужно сделать:

// 1. Поэлементное сравнение — тяжелая, не универсальная работа HashCodeExampleWorking toTest = obj as HashCodeExampleWorking; if (toTest.val == this.val) {

if( toTest.buf == this.buf) { return true;

‘ }

}

// или

// 2. Сравнение с отражением

12 Зак. 555

II или

// 3. Сравнение результатов метола ToString():

.//   что если метол не подменяется или это должно быть стандартной

//   практикой наподобие методов GetHashCode() и Equals()

}

return false;

}

Реализуемая в методе Equals о логика сначала тестирует оба типа на  идентиость. В случае отрицательного результата возвращается false. Далее выполняется проверка на возвращение методом GetHashCode () неодинаковых значений. Метод GetHashCode о всегда должен возвращать различные значения для объектов, имеющих разные члены данных. Если же значения хэш-кодов одинаковые, то слует тяжелая работа индивидуального тестирования каждого члена данных на ренство. Этот шаг оставляется напоследок, т. к. любой объект, достигнувший этой стадии, скорее всего, будет идентичен уже существующему объекту, но нам нужно быть уверенными на все 100%.

Источник: Гросс  К. С# 2008:  Пер. с англ. — СПб.:  БХВ-Петербург, 2009. — 576 е.:  ил. — (Самоучитель)

По теме:

  • Комментарии