Переопределение System.Object. Equals()
Переопределение System.Object. Equals()
Давайте переопределим и поведение System.Object.Equals(), чтобы иметь возможность работать с семантикой, основанной на значениях. Напомним, что по умолчанию Equals() возвращает true (истина), когда обе сравниваемые ссылки указывают на один и тот же объект в динамической памяти. Однако часто бывает нужно не то, чтобы две ссылки указывали на один объект в памяти, а чтобы два объекта имели одинаковые состояния (в случае Person это означает равенство значений name, SSN и age).
public override bool Equals(object о) {
// Убедимся, что вызывающая сторона посылает
// действительный объект Person.
if (о!= null && о is Person) {
// Теперь проверим, что данный объект Person
// и текущий объект (this) несут одинаковую информацию.
Person temp = (Person)о;
if (temp.firstName == this.firstName && temp.lastName == this.lastName && temp.SSN == this.SSN && temp.age == this.age) return true;
}
return falsе; // He одинаковую!
}
Здесь с помощью ключевого слова is языка C# вы сначала проверяете, что вызывающая сторона действительно передает методу Equals() объект Person. После этого нужно сравнить значение поступающего параметра со значениями полей данных текущего объекта (обратите внимание на использование ключевого слова this, которое ссылается на текущий объект).
Прототип System.Object.Equals() предполагает получение единственного аргумента типа object. Поэтому вы должны выполнить явный вызов метода Equals(), чтобы получить доступ к членам типа Person. Если значения name, SSN и age двух объектов будут идентичны, вы имеете два объекта с одинаковыми данными состояния, поэтому возвратится true (истина). Если какие-то данные будут различаться, вы получите false (ложь).
Переопределив System.Object.ToString() для данного класса, вы получаете очень простую возможность переопределения System.Object.Equals(). Если возвращаемое из ToString() значение учитывает все члены текущего класса (и данные базовых классов), то метод Equals() может просто сравнить значения соответствующих строковых типов.
public override bool Equals(object o) {
if (o != null && о is Person) {
Person temp = (Person)o;
if (this.ToString() == о.ToString()) return true;
else return false;
}
return false;
}
Теперь предположим, что у нас есть тип Car (автомобиль), экземпляр которого мы попытаемся передать методу Person.Equals().
// Автомобили – это не люди!
Car с = new Car();
Person p = new Person();
p.Equals(c);
Из-за проверки в среде выполнения на "истинность" объекта Person (с помощью оператора is) метод Equals() возвратит false. Теперь рассмотрим следующий вызов.
// Ой!
Person р = new Person();
p.Equals(null);
Это тоже не представляет опасности, поскольку наша проверка предусматривает возможность поступления пустой ссылки.
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКЧитайте также
А.5. Common Lisp Object System (CLOS)
А.5. Common Lisp Object System (CLOS) Происхождение Существуют буквально десятки диалектов языка Lisp, включая MacLisp, Standard Lisp, SpiceLisp, S-1 Lisp, ZetaLisp, Nil, InterLisp и Scheme. В начале 80-х годов под воздействием идей объектно-ориентированного программирования возникла серия новых диалектов Lisp, многие из
Мастер-класс: System.Object
Мастер-класс: System.Object Совет. Следующий обзор System.Object предполагает, что вы знакомы с понятиями виртуального метода и переопределения методов. Если мир ООП для вас является новым, вы можете вернуться к этому разделу после изучения материала главы 4.В .NET каждый тип в конечном
Переопределение элементов System.Object, заданных по умолчанию
Переопределение элементов System.Object, заданных по умолчанию Хотя заданное по умолчанию поведение System.Object может оказаться вполне приемлемым в большинстве случаев, вполне обычным для создаваемых вами типов будет переопределение некоторых из унаследованных методов. В главе
Переопределение System.Object.ToString()
Переопределение System.Object.ToString() Переопределение метода ToString() дает возможность получить "снимок" текущего состояния объекта. Это может оказаться полезным в процессе отладки. Для примера давайте переопределим System.Object.ToString() так, чтобы возвращалось текстовое представление
Переопределение System.Object.GetHashCode()
Переопределение System.Object.GetHashCode() Если класс переопределяет метод Equals(), следует переопределить и метод System.Object.GetHashCode(). Не сделав этого, вы получите предупреждение компилятора. Роль GetHashCode() – возвратить числовое значение, которое идентифицирует объект в зависимости от его
Статические члены System.Object
Статические члены System.Object В завершение нашего обсуждения базового класса .NET, находящегося на вершине иерархии классов, следует отметить, что System.Object определяет два статических члена (Object.Equals() и Object.ReferenceEquals()), обеспечивающих проверку на равенство значений и ссылок
System.DateTime и System.TimeSpan
System.DateTime и System.TimeSpan В завершение нашего обзора базовых типов данных позволите обратить ваше внимание на то, что пространство имен System определяет несколько полезных типов данных, для которых в C# не предусмотрено ключевых слов. Это, в частности, типы DateTime и TimeSpan (задачу
Переопределение System.Object.Finalize()
Переопределение System.Object.Finalize() В тех редких случаях, когда воздается C#-класс, использующий неуправляемые ресурсы, нужно гарантировать, что соответствующая память будет обрабатываться прогнозируемым образом. Предположим, что вы создали класс MyResourceWrapper, использующий
Базовые классы System.MulticastDelegate и System.Delegate
Базовые классы System.MulticastDelegate и System.Delegate Таким образом, при создании типов c помощью) ключевого слова delegate в C# вы неявно объявляете тип класса, являющегося производным от System.MulticastDelegate. Этот класс обеспечивает своим потомкам доступ к списку с адресами тех методов, которые
Снова о создании объектных образов, восстановлении значений и System.Object
Снова о создании объектных образов, восстановлении значений и System.Object Чтобы понять, в чем заключаются преимущества использования обобщений, следует выяснить, какие проблемы возникают у программиста без их использования. Вы должны помнить из главы 3, что платформа .NET
Получение Туре с помощью System.Object.GetType()
Получение Туре с помощью System.Object.GetType() Экземпляр класса Туре можно получить множеством способов. Нельзя только непосредственно создать объект Туре, используя для этого ключевое слово new, поскольку класс Туре является абстрактным. Чтобы привести пример одной из
Переопределение (redefinition)
Переопределение (redefinition) Когда класс является наследником другого класса, может потребоваться изменить реализацию или другие свойства некоторых наследованных компонент. Класс SESSION, управляющий сеансами пользователей в операционной системе, может иметь компонент terminate,
Переопределение и утверждения
Переопределение и утверждения Если клиент класса POLYGON вызывает p.perimeter, то он ожидает получить значение периметра p, определенное спецификацией функции perimeter в определении этого класса. Но теперь, благодаря динамическому связыванию, клиент может вызвать другую программу,
Явное переопределение
Явное переопределение Роль предложения redefine состоит в улучшении читаемости и надежности. Компиляторам, на самом деле, оно не нужно, так как в классе может быть лишь один компонент с данным именем, то объявленный в данном классе компонент, имеющий то же имя, что и компонент