Фитнесс без Фокусов

Вот утверждение, которое я прочитал вчера про сравнения объектов ссылочного типа в C#:

Object.ReferenceEquals(x,y) возвращает true если, и только если, x и y ссылаются на один и тот же объект.

Правда или нет?

Моя жена Лея недавно купила Хонду Фит, спасибо имманентному отказу в соленоидах автоматической коробки передач её старой Хонды Цивик. Задние сиденья Фита складываются в плоскость. В эту штуку можно загнать ламу, или целую кучу хула-хупов, или всё что угодно. Это весьма удобно. Не то, что я называю мощным движком, но для быстрых поездок по городу она – то, что надо.

Поскольку мы были женаты, когда она купила машину, и продолжаем состоять в браке, что моё – то её, и что её – то моё. Так что если x = Хонда Фит Эрика, а y = Хонда Фит Леи, то x и y «ссылочно эквивалентны». Эти две вещи ссылаются на один и тот же объект, тот блестящий чёрный объект, полный лам и хула-хупов, который стоит возле моего дома.

Теперь, мы могли купить другую машину. Скажем, Форд Фокус. Но мы не купили. У нас в сумме ноль Фордов Фокусов. Предположим, я сказал, что x = Форд Фокус Эрика, а y = Форд Фокус Леи. Каков осмысленный способ охарактеризовать природу x и y? Должны ли мы сказать, что обе они ссылаются на один и тот же Форд Фокус, а именно на несуществующий Форд Фокус? Разум колеблется от неприемлемого и парадоксального предположения о том, что где-то существует Форд Фокус, который является несуществующим Фордом Фокус!(*) Скорее, верный способ охарактеризовать это в том, чтобы сказать, что ни x ни y не ссылаются ни на какой объект. Это «пустые ссылки» - ссылки, которые ни на что не ссылаются, а, скорее, имеют значение «отсутствия ссылаемого».

И именно поэтому неверно говорить, что Object.ReferenceEquals(x,y) возвращает true если, и только если, x и y ссылаются на один и тот же объект. Если x и y не ссылаются на объекты, то они явно не ссылаются на один и тот же объект, потому что никто из них не ссылается на объект вообще. Корректный способ охарактеризовать поведение ссылочной эквивалентности в том, что Object.ReferenceEquals(x,y) возвращает true если, и только если , либо x и y ссылаются на один и тот же объект, либо и x и y – пустые ссылки.

***********

(*) И я по-прежнему фанат «null object pattern». Жизнь полна этих маленьких противоречий.

[Эрик на этой неделе в отпуске, пост был предварительно записан]