В основном, посмотрим на такой замечательный оператор, как ==, и сравнение в языке вообще.

Маразм первый, широко распространенный

Заключается в том, что null - не объект. Всем известно, что null равен null. Для сравнения объектов можно было бы использовать Equals. Тогда код, которому наплевать на типы объектов, но который интересуется равенством объектов, мог бы выглядеть следующим образом:
Object o1, o2;
return o1.Equals(o2);
Увы, это не работает. null не объект, у него нет метода Equals. Получаем exception. Тот непонятный факт, что null не является объектом, известен нам еще по Java и разумного объяснения не имеет. С другой стороны, == успешно срабатывает для null. Может быть, нам поможет перегрузка операций?

Маразм второй - неполиморфные операторы

Попробуем нарисовать класс, все экземпляры которого равны между собой:
class My {
  public override bool Equals(object o) {
    return o is My;
  }
}

Все компилируется и работает как ожидалось:

  object o1 = new My(), o2 = new My();  
  return o1.Equals(o2); // true

Теперь добавим оператор:

class My {
  public override bool Equals(object o) {
    return o is My;
  }
  public static bool operator == (My m1, My m2) {
    return m1.Equals(m2);
  }

  //...... Здесь куча всего необходимого, см. следующий маразм
}
Может быть, теперь все станет хорошо? Если Вы так думаете, вас ждет разочарование:
  My m1 = new My(), m2 = new My();
  bool result = (m1 == m2); //true, как и ожидалось
  object o1=m1, o2=m2;
  result = (o1 == o2); // false, чего тоже можно было ожидать из синтаксиса
Да здравствует полиморфизм! Всем желающим это отлаживать - большой привет (бага в отладчике на эту тему уже найдена)

Маразм третий

  1. Перегружая == вы обрекаете себя на перегрузку GetHashCode(). Парная перегрузка метода сравнения и получения hash-кода - хорошая практика. Это, в частности, требуется при использовании hash-множеств. Но встает вопрос, почему не требуется перегрузка GetHashCode() при перегрузке Equals?!!! Только не надо думать, что hash множества хэшируют объекты по GetHashCode, а сравнивают по == :))) Иначе все объекты сравнивались в смысле Object - на идентичность.
  2. Перегружая == вы обрекаете себя на перегрузку !=. Специально для людей с детства ненавидевших принцип исключения третьего :) Ок, пусть нам нужны вещи, которые могут быть не равны, и не неравны (примеры welcome). Но может быть стоило предоставить что-нибудь по умолчанию, а? Например, если перегрузить +, то += работает вполне логично...


Hosted by uCoz