Сравнение ссылочных типов на эквивалентность 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Сравнение ссылочных типов на эквивалентность



Один аспект System.Object, который на первый взгляд может показаться неожидан­ным - это тот факт, что в нем определены три разных метода ддя проверки эквивалентно­сти объектов: ReferenceEquals() и две версии Equals(). Добавьте сюда операцию срав­нения (==) и вы получите четыре способа проверки равенства. Между этими способами существуют тонкие отличия, которые описаны ниже.

Метод ReferenceEquals()

ReferenceEquals() - статический метод, проверяющий, указывают ли две ссылки на один и тот же экземпляр класса; точнее - содержат ли две ссылки один и тот адрес памяти. Поскольку это статический метод, который невозможно переопределить, его реализация из System.Object - это то, что доступно всегда. ReferenceEquals() всегда будет возвра­щать true, когда ему передаются две ссылки, указывающие на один и тот же экземпляр объ­екта, и false - в противном случае. Однако две ссылки на null трактуются как равные:

SomeClass х, у;

х = new SomeClass();

у = new SomeClass();

bool В1 = ReferenceEquals(null,null); //возвращает true

bool B2 = ReferenceEquals(null,x); //возвращает false

bool B3 = ReferenceEquals (x, у); //возвращает false, потому что

// x и у указывают на разные объекты

Виртуальный метод Equals()

Реализация System.Object виртуальной версии Equals() также сравнивает ссылки. Однако, поскольку этот метод виртуальный, его можно переопределять в собственных классах, чтобы сравнивать объекты по значению. В частности, если вы намерены исполь­зовать экземпляры своего класса в качестве ключей словаря, то должны переопределить этот метод для сравнения значений. В противном случае, в зависимости от того, как вы пе­реопределите

Object.HashCode(), класс словаря, содержащий объекты, может либо вооб­ще не работать, либо работать крайне неэффективно. Об одном моменте следует помнить, переопределяя Equals(): ваша версия этого метода не должна генерировать исключения. В противном случае это может стать причиной проблем для классов словарей, а также, воз­можно, и для других базовых классов.NET, которые внутренне вызывают этот метод.

Статический метод Equals()

Статическая версия Equals() в действительности делает то же самое, что и виртуаль­ная версия уровня экземпляра. Разница в том, что статическая версия принимает два пара­метра и проверяет их на предмет равенства. Этот метод справляется с ситуацией, когда обе ссылки равны null, а потому обеспечивает дополнительную защиту от генерации исключе­ний, когда существует риск, что оба объекта окажутся равными null. Статическая версия первым делом проверяет переданные ей ссылки на предмет равенства их null. Если они обе равны null, возвращается true (поскольку ссылка null трактуется как равная другой ссылке null). Если только одна из ссылок равна null, возвращается false. Если обе ссыл­ки на самом деле указывают на что-либо, вызывается версия Equals() уровня экземпляра. Это значит, что если вы переопределите виртуальный метод Equals() уровня экземпляра, то эффект будет такой, как если бы вы переопределили и статическую версию также.

Операция сравнения (==)

Операцию сравнения можно рассматривать как промежуточный выбор между строгим сравнением значений и строгим сравнением ссылок. В большинстве случаев конструкция

bool b = (х == у); // х, у - объектные ссылки

означает, что сравниваются ссылки. Однако возможно существование классов, для кото­рых более естественным и интуитивно ожидаемым будет трактовка сравнения значений. В таких случаях лучше переопределить эту операцию, чтобы она сравнивала значения. Переопределение операций рассматривается ниже, но очевидным примером может слу­жить класс System.String, для которого Microsoft переопределила операцию с тем, что­бы она сравнивала содержимое строк, а не их ссылки.



Поделиться:


Последнее изменение этой страницы: 2016-12-30; просмотров: 128; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.16.83.150 (0.005 с.)