简体   繁体   中英

I thought Object.Equals(Object, Object) support bitwise equality and not value equality

Static method Object.Equals(Object, Object) supports reference equality for reference types, and bitwise equality for value types, where with bitwise equality the objects that are compared have the same binary representation, while value equality objects compared have the same value even though they have different binary representations.

For example, since i1 and b1 are of different types, they don't have the same binary representation and thus Object.Equals(Object, Object) returns false :

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

Object.Equals(Object, Object) should also return false when comparing d1 and d2 ( since the two variables have different binary representation of the same value ), but it instead returns true , which suggests that it compares them using value equality:

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

Shouldn't Object.Equals(Object, Object) return False when comparing d1 and d2 ?

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

For example, consider two Decimal objects that represent the numbers 1.10 and 1.1000. The Decimal objects do not have bitwise equality because they have different binary representations to account for the different number of trailing zeroes.

thanx

Decimal is a value type and Equals method actually compares all its fields using Reflection. For more details, please refer to the MSDN:

ValueType.Equals Method

Finally, your scope from the MSDN is incomplete. Here it is:

For example, consider two Decimal objects that represent the numbers 1.10 and 1.1000. The Decimal objects do not have bitwise equality because they have different binary representations to account for the different number of trailing zeroes. However, the objects have value equality because the numbers 1.10 and 1.1000 are considered equal for comparison purposes since the trailing zeroes are insignificant.

Object.Equals SHOULD implement value (not bitwise) equality.

In the Decimal case, both objects are of the same type and the values are equal, so the result is true.

In the int, byte case, objects are of different type, so the result is false.

You can look at the source of Object.Equals(Object, Object) with a tool like reflector.

Here's the source code of Object.Equals(Object, Object):

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

Let's examine the clauses:

(objA == objB) : This is the object equality operator which checks to see if these two objects reference the same object. This clause is false for our case.

(objA != null) && (objB != null) : This is true for our case.

objA.Equals(objB) : This is true (it delegates to Decimal.Equals(Object))

We've got all true on the RHS of the || operator, so the whole statement evaluates to true.

From MSDN:

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

Note that a derived type might override the Equals method to implement value equality. Value equality means the compared objects have the same value but different binary representations.

Decimal definitely has an Equals override, as can be seen in the metadata.

Object.Equals(Object objA, Object objB) first does a quick reference check ( objA == objB ). If that fails, it tries to call the virtual Object.Equals(Object obj) which Decimal overrides to provide value equality.

No way, bitwise equality does not make sense and it is never correct. Whatever is stored in whichever bitwise format, we do not care we care for actual business value.

For business or science purpose 1.10 and 1.100 are same. Bitwise comparison means lexical comparison, which is wrong. "1.10" an "1.100" are different as they represent incorrect lexical sequence.

If you want to compare actual bits then you should use BitConverter.GetBytes which will give you actual bit sequence.

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

I don't know if there is an Array.Compare method or not but you can create one and hope you got the point.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM