ЯЗЫК ПРОГРАММИРОВАНИЯ С# 2005 И ПЛАТФОРМА .NET 2.0. 3-е издание
Шрифт:
Теперь предположим, что у нас есть тип Car (автомобиль), экземпляр которого мы попытаемся передать методу Person.Equals.
Из-за проверки в среде выполнения на "истинность"
Это тоже не представляет опасности, поскольку наша проверка предусматривает возможность поступления пустой ссылки.
Переопределение System.Object.GetHashCode
Если класс переопределяет метод Equals, следует переопределить и метод System.Object.GetHashCode. Не сделав этого, вы получите предупреждение компилятора. Роль GetHashCode – возвратить числовое значение, которое идентифицирует объект в зависимости от его состояния. И если у вас есть два объекта Person, имеющие идентичные значения name, SSN и age, то вы должны получить для них одинаковый хеш-код.
Вообще говоря, переопределение этого метода может понадобиться только тогда, когда вы собираетесь сохранить пользовательский тип в коллекции, использующей хеш-коды, например, в System.Collections.Hashtable. В фоновом режиме тип Hashtable вызывает Equals и GetHashCode содержащихся в нем типов, чтобы определить правильность объекта, возвращаемого вызывающей стороне. Поскольку System.Object не имеет информации о данных состояния для производных типов, вы должны переопределить GetHashCode для всех типов, которые вы собираетесь хранить в Hashtable.
Есть много алгоритмов, которые можно использовать для создания хеш-кода, как "изощренных", так и достаточно "простых". Еще раз подчеркнем, что значение хеш-кода объекта зависит от состояния этого объекта. Класс System.String имеет довольно солидную реализацию GetHashCode, основанную на значении символьных данных. Поэтому, если можно найти строковое поле, которое будет уникальным для всех рассматриваемых объектов (например, поле SSN для объектов Person), то можно вызвать GetHashCode для строкового представлении такого поля.
Если вы не сможете указать подходящий элемент данных, но переопределите ToString, то можно просто возвратить хеш-код строки, возвращенной вашей реализацией ToString.
Тестирование
Теперь можно проверить обновленный класс Person. Добавьте следующий программный код в метод Main и сравните результат его выполнения с тем, что показано на рис. 3.18.
Рис. 3.18. Результаты переопределения членов System.Object
Статические члены System.Object
В завершение нашего обсуждения базового класса .NET, находящегося на вершине иерархии классов, следует отметить, что System.Object определяет два статических члена (Object.Equals и Object.ReferenceEquals), обеспечивающих проверку на равенство значений и ссылок соответственно. Рассмотрим следующий программный код.