Я думал, что Object.Equals(Object, Object) поддерживает поразрядное равенство, а не равенство равенства

Статический метод Object.Equals(Object, Object) поддерживает ссылочное равенство для ссылочных типов и побитовое равенство для типов значений, где с поразрядным равенством сравниваемые объекты имеют одно и то же двоичное представление, в то время как сравниваемые объекты равенства равноценны, даже если они имеют различные двоичные представления.

Например, поскольку i1 и b1 имеют разные типы, они не имеют одного и того же двоичного представления и, следовательно, Object.Equals(Object, Object) возвращает false:

        int  i1 = 100;
        byte b1 = 100;
        Console.WriteLine(Object.Equals(i1, b1));//false

Object.Equals(Object, Object) должен также возвращать значение false при сравнении d1 и d2 (так как две переменные имеют различное двоичное представление того же значения), но вместо этого возвращает true, что предполагает, что он сравнивает их с использованием значения равенство:

        decimal d1 = 1.10M;
        decimal d2 = 1.100M;
        Console.WriteLine(Object.Equals(d1, d2)); //true

Не следует ли Object.Equals(Object, Object) возвращать False при сравнении d1 и d2?

Из http://msdn.microsoft.com/en-us/library/bsc2ak47.aspx:

Например, рассмотрим два десятичных объекты, которые представляют числа 1.10 и 1.1000. Десятичные объекты не имеют побитового равенства, потому что у них разные бинарные представительств для учета разное количество конечных нулей.

спасибо

Ответы

Ответ 1

Decimal - это тип значения, а метод Equals фактически сравнивает все его поля с помощью Reflection. Для получения дополнительной информации обратитесь к MSDN:

Метод ValueType.Equals

Наконец, ваша область действия из MSDN неполна. Вот он:

Например, рассмотрим два десятичных объекты, которые представляют числа 1.10 и 1.1000. Десятичные объекты не имеют побитового равенства, потому что у них разные бинарные представительств для учета разное количество конечных нулей. Однако объекты имеют ценность равенство, поскольку числа 1.10 и 1.1000 считаются равными для целей сравнения, поскольку конечный нули незначительны.

Ответ 2

Object.Equals СЛЕДУЕТ реализовать значение (не побитовое) равенство.

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

В случае int, byte объекты имеют разный тип, поэтому результат является ложным.

Ответ 3

Вы можете посмотреть на источник Object.Equals(Object, Object) с помощью инструмента, такого как отражатель.

Здесь исходный код объекта Object.Equals(Object, Object):

public static bool Equals(object objA, object objB)
{
    return ((objA == objB) || (((objA != null) && (objB != null)) && objA.Equals(objB)));
}

Давайте рассмотрим предложения:

(objA == objB): Это оператор равенства объекта, который проверяет, ссылаются ли эти два объекта на один и тот же объект. Этот пункт является ложным для нашего случая.

(objA != null) && (objB != null): Это верно для нашего случая.

objA.Equals(objB): Это верно (он делегирует Decimal.Equals(Object))

У нас есть все true на RHS оператора ||, поэтому весь оператор оценивается как true.

Ответ 4

Из MSDN:

http://msdn.microsoft.com/en-us/library/w4hkze5k.aspx

Обратите внимание, что производный тип может переопределить метод Equals для реализации равенства значений. Значение равенства означает, что сравниваемые объекты имеют одинаковое значение, но разные двоичные представления.

Десятичная определенность имеет переопределение Equals, как видно из метаданных.

Ответ 5

Object.Equals(Object objA, Object objB) сначала выполняет быструю контрольную проверку (objA == objB). Если это не удается, он пытается вызвать виртуальный Object.Equals(Object obj), который Decimal переопределяет для обеспечения равенства значений.

Ответ 6

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

Для деловых или научных целей 1.10 и 1.100 одинаковы. Поразрядное сравнение означает лексическое сравнение, что неверно. "1.10" "1.100" различны, так как они представляют собой неправильную лексическую последовательность.

Если вы хотите сравнить фактические биты, вы должны использовать BitConverter.GetBytes, который даст вам фактическую последовательность бит.

Array.Compare( 
   BitConverter.GetBytes((decimal)1.10),
   BitConverter.GetBytes((decimal)1.100))

Я не знаю, есть ли метод Array.Compare или нет, но вы можете создать его и надеяться, что у вас получится.