Подтвердить что ты не робот

Почему (объект) 0 == (объект) 0 отличается от ((объект) 0).Equals((object) 0)?

Почему следующие выражения отличаются?

[1]  (object)0 == (object)0 //false
[2]  ((object)0).Equals((object)0) // true

Собственно, я могу полностью понять [1], потому что, возможно,.NET runtime будет box целочисленным и начнет сравнивать ссылки вместо этого. Но почему [2] отличается?

4b9b3361

Ответ 1

Причина, по которой вызовы ведут себя по-другому, - это привязка к очень различным методам.

Случай == будет привязан к оператору равенства статических ссылок. Существует 2 независимых значения в коробке int, поэтому они не являются одинаковыми.

Во втором случае вы привязываетесь к методу экземпляра Object.Equals. Это виртуальный метод, который будет фильтроваться до Int32.Equals, и это проверяет целое число в штучной упаковке. Оба целочисленных значения равны 0, поэтому они равны

Ответ 2

Когда вы передаете значение int 0 (или любой другой тип значения) на object, значение вставляется в квадрат. Каждый приведение к object создает другой блок (т.е. Другой экземпляр объекта). Оператор == для типа object выполняет сравнение ссылок, поэтому он возвращает false, так как левая и правая стороны не являются одним и тем же экземпляром.

С другой стороны, когда вы используете Equals, который является виртуальным методом, он использует реализацию фактического бокс-типа, то есть Int32.Equals, который возвращает true, поскольку оба объекта имеют одинаковое значение.

Ответ 3

Оператор ==, статичный, не является виртуальным. Он будет запускать точный код, который определяет класс object (`object - тип времени компиляции операндов), который будет выполнять сравнение ссылок, независимо от типа среды выполнения любого объекта.

Метод Equals - это метод виртуального экземпляра. Он будет запускать код, определенный в фактическом типе времени выполнения (первый), а не в коде класса object. В этом случае объект является int, поэтому он будет выполнять сравнение значений, так как это тип int определяет его метод Equals.

Ответ 4

Метод Equals() является виртуальным.
Поэтому он всегда называет конкретную реализацию, даже когда callsite выставляется на object. int переопределяет Equals() для сравнения по значению, поэтому вы получаете сравнение значений.

Ответ 5

== Использование: Object.ReferenceEquals

Object.Equals сравнивает значение.

Метод Object.ReferenceEquals сравнивает ссылки. Когда вы выделяете объект, вы получаете ссылку, содержащую значение, указывающее его ячейку памяти, в дополнение к данным объекта в куче памяти.

Метод Object.Equals сравнивает содержимое объектов. Сначала он проверяет, равны ли ссылки, равно как и object.ReferenceEquals. Но затем он вызывает производные методы Equals для дальнейшего тестирования равенства. Смотрите это:

   System.Object a = new System.Object();
System.Object b = a;
System.Object.ReferenceEquals(a, b);  //returns true

Ответ 6

Оператор С# использует токен == для представления двух разных операторов: статически перегружаемого оператора сравнения и неперегружаемого оператора сравнения ссылок. Когда он встречает токен ==, он сначала проверяет, существует ли какая-либо перегрузка перегрузки равенства, которая применима к типам операндов. Если это так, он будет ссылаться на эту перегрузку. В противном случае он проверяет, применимы ли типы к оператору сравнения ссылок. Если это так, он будет использовать этот оператор. Если ни один из операторов не применим к типам операндов, компиляция завершится с ошибкой.

Код (Object)0 не просто увеличивает значение Int32 до Object: Int32, как и все типы значений, фактически представляет два типа, один из которых описывает значения и места хранения (такие как буквальный ноль), но не получается ни от чего, и один из них описывает объекты кучи и выводится из Object; потому что только последний тип может быть upcast до Object, компилятор должен создать новый кучный объект этого последнего типа. Каждый вызов (Object)0 создает новый объект кучи, поэтому два операнда в == представляют собой разные объекты, каждый из которых независимо независимо инкапсулирует значение Int32 0.

Класс Object не имеет допустимых перегрузок, определенных для оператора equals. Следовательно, компилятор не сможет использовать перегруженный оператор проверки равенства и снова вернется к использованию теста равенства ссылок. Поскольку два операнда до == относятся к отдельным объектам, он сообщает false. Второе сравнение выполняется успешно, потому что он запрашивает один экземпляр объекта кучи Int32, независимо от того, совпадает ли он с другим. Поскольку этот экземпляр знает, что значит быть равным другому отдельному экземпляру, он может ответить true.

Ответ 7

Обе проверки разные. Первый проверяет личность, второй - на равенство. В общем случае два члена идентичны, если они ссылаются на один и тот же объект. Это означает, что они равны. Два члена равны, если их значения одинаковы.

В терминах программирования идентичность обычно вызывается ссылочным равенством. Если указатель на оба условия равен (!), Объект, на который они указывают, является точно таким же. Однако, если указатели отличаются, значение объектов, на которые они указывают, все равно может быть одинаковым. В идентификаторе С# можно проверить, используя статический член Object.ReferenceEquals, в то время как равенство проверяется с использованием нестатического члена Object.Equals. Так как вы бросаете два целых числа в объекты (которые называются "бокс", btw), operatior == of object выполняет первую проверку, которая по умолчанию отображается на Object.ReferenceEquals и проверяет идентификатор. Если вы объясните, что нестатический Equals -member, динамическая отправка приводит к вызову Int32.Equals, который проверяет равенство.

Оба понятия похожи, но не то же самое. Сначала они могут показаться запутанными, но небольшая разница очень важна! Представьте себе двух человек, а именно "Алиса" и "Боб". Они оба живут в желтом доме. Исходя из предположения, что Алиса и Боб живут в районе, где дома отличаются только своим цветом, они могут жить в разных желтых домах. Если вы сравните оба дома, вы узнаете, что они абсолютно одинаковы, потому что они оба желтые! Однако они не разделяют один и тот же дом, и поэтому их дома равны, но не идентичны. Идентичность означает, что они живут в одном доме.

Примечание: некоторые языки определяют оператор === для проверки идентичности.