Читаем Язык программирования C#9 и платформа .NET5 полностью

При переопределении метода ToString для класса, расширяющего специальный базовый класс, первым делом необходимо получить возвращаемое значение ToString из родительского класса, используя ключевое слово base. После получения строковых данных родительского класса их можно дополнить специальной информацией производного класса.

Переопределение метода System.Object.Equals

Давайте также переопределим поведение метода Object.Equals, чтобы работать с семантикой на основе значений. Вспомните, что по умолчанию Equals возвращает true, только если два сравниваемых объекта ссылаются на один и тот же экземпляр объекта в памяти. Для класса Person может оказаться полезной такая реализация Equals, которая возвращает true, если две сравниваемые переменные содержат те же самые значения состояния (например, фамилию, имя и возраст).

Прежде всего, обратите внимание, что входной аргумент метода Equals имеет общий тип System.Object. В связи с этим первым делом необходимо удостовериться в том, что вызывающий код действительно передал экземпляр типа Person, и для дополнительной подстраховки проверить, что входной параметр не является ссылкой null.

После того, как вы установите, что вызывающий код передал выделенный экземпляр Person, один из подходов предусматривает реализацию метода Equals для сравнения поле за полем данных входного объекта с данными текущего объекта:


public override bool Equals(object obj)

{

  if (!(obj is Person temp))

  {

    return false;

  }

  if (temp.FirstName == this.FirstName

      && temp.LastName == this.LastName

      && temp.Age == this.Age)

  {

    return true;

  }

  return false;

}


Здесь производится сравнение значений входного объекта с внутренними значениями текущего объекта (обратите внимание на применение ключевого слова this). Если имя, фамилия и возраст в двух объектах идентичны, то эти два объекта имеют одинаковые данные состояния и возвращается значение true. Любые другие результаты приводят к возвращению false.

Хотя такой подход действительно работает, вы определенно в состоянии представить, насколько трудоемкой была бы реализация специального метода Equals для нетривиальных типов, которые могут содержать десятки полей данных. Распространенное сокращение предусматривает использование собственной реализации метода ToString. Если класс располагает подходящей реализацией ToString, в которой учитываются все поля данных вверх по цепочке наследования, тогда можно просто сравнивать строковые данные объектов (проверив на равенство null):


// Больше нет необходимости приводить obj к типу Person,

// т.к. у всех типов имеется метод ToString.

public override bool Equals(object obj)

  => obj?.ToString == ToString;


Обратите внимание, что в этом случае нет необходимости проверять входной аргумент на принадлежность к корректному типу (Person в нашем примере), поскольку метод ToString поддерживают все типы .NET. Еще лучше то, что больше не требуется выполнять проверку на предмет равенства свойство за свойством, т.к. теперь просто проверяются значения, возвращаемые методом ToString.

Переопределение метода System.Object.GetHashCode

В случае переопределения в классе метода Equals вы также должны переопределить стандартную реализацию метода GetHashCode. Выражаясь упрощенно, хеш-код — это числовое значение, которое представляет объект как специфическое состояние. Например, если вы создадите две переменные типа string, хранящие значение Hello, то они должны давать один и тот же хеш-код. Однако если одна из них хранит строку в нижнем регистре (hello), то должны получаться разные хеш-коды.

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


На заметку! Говоря точнее, класс System.Collections.Hashtable внутренне вызывает метод GetHashCode, чтобы получить общее представление о местоположении объекта, а с помощью последующего (внутреннего) вызова метода Equals определяет его точно.


Перейти на страницу:

Похожие книги

Программирование. Принципы и практика использования C++ Исправленное издание
Программирование. Принципы и практика использования C++ Исправленное издание

Специальное издание самой читаемой и содержащей наиболее достоверные сведения книги по C++. Книга написана Бьярне Страуструпом — автором языка программирования C++ — и является каноническим изложением возможностей этого языка. Помимо подробного описания собственно языка, на страницах книги вы найдете доказавшие свою эффективность подходы к решению разнообразных задач проектирования и программирования. Многочисленные примеры демонстрируют как хороший стиль программирования на С-совместимом ядре C++, так и современный -ориентированный подход к созданию программных продуктов. Третье издание бестселлера было существенно переработано автором. Результатом этой переработки стала большая доступность книги для новичков. В то же время, текст обогатился сведениями и методиками программирования, которые могут оказаться полезными даже для многоопытных специалистов по C++. Не обойдены вниманием и нововведения языка: стандартная библиотека шаблонов (STL), пространства имен (namespaces), механизм идентификации типов во время выполнения (RTTI), явные приведения типов (cast-операторы) и другие. Настоящее специальное издание отличается от третьего добавлением двух новых приложений (посвященных локализации и безопасной обработке исключений средствами стандартной библиотеки), довольно многочисленными уточнениями в остальном тексте, а также исправлением множества опечаток. Книга адресована программистам, использующим в своей повседневной работе C++. Она также будет полезна преподавателям, студентам и всем, кто хочет ознакомиться с описанием языка «из первых рук».

Бьёрн Страуструп , Ирина Сергеевна Козлова , Бьерн Страуструп , Валерий Федорович Альмухаметов

Программирование, программы, базы данных / Базы данных / Программирование / Учебная и научная литература / Образование и наука / Книги по IT
97 этюдов для архитекторов программных систем
97 этюдов для архитекторов программных систем

Успешная карьера архитектора программного обеспечения требует хорошего владения как технической, так и деловой сторонами вопросов, связанных с проектированием архитектуры. В этой необычной книге ведущие архитекторы ПО со всего света обсуждают важные принципы разработки, выходящие далеко за пределы чисто технических вопросов.?Архитектор ПО выполняет роль посредника между командой разработчиков и бизнес-руководством компании, поэтому чтобы добиться успеха в этой профессии, необходимо не только овладеть различными технологиями, но и обеспечить работу над проектом в соответствии с бизнес-целями. В книге более 50 архитекторов рассказывают о том, что считают самым важным в своей работе, дают советы, как организовать общение с другими участниками проекта, как снизить сложность архитектуры, как оказывать поддержку разработчикам. Они щедро делятся множеством полезных идей и приемов, которые вынесли из своего многолетнего опыта. Авторы надеются, что книга станет источником вдохновения и руководством к действию для многих профессиональных программистов.

Нил Форд , Билл де Ора , Майкл Хайгард

Программирование, программы, базы данных / Базы данных / Программирование / Книги по IT