Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why does equals not work the same when items are cast to object?

Tags:

c#

when i cast int and float to object and compare them the equality is always false. Why?

        float f = 0.0f;
        int i = 0;
        Console.WriteLine(f.Equals(i)); // true
        Console.WriteLine(i.Equals(f)); // false
        Console.WriteLine(i == f); // true
        Console.WriteLine("----------------");
        object obf = f;
        object obi = i;
        Console.WriteLine(obf.Equals(obi)); // false
        Console.WriteLine(obi.Equals(obf)); // false
        Console.WriteLine(obi == obf); // false
        Console.WriteLine("----------------");

Update: this is NOT the case for the same type

        int i1 = 1;
        int i2 = 1;
        object oi1 = i1;
        object oi2 = i2;
        Console.WriteLine(oi1.Equals(oi2)); // true
        Console.WriteLine(oi2.Equals(oi1)); // true
like image 808
Charles Lambert Avatar asked Oct 27 '11 15:10

Charles Lambert


People also ask

Can you use equals () with objects?

The equals() method is a static method of the Objects class that accepts two objects and checks if the objects are equal. If both the objects point to null , then equals() returns true .

Is it possible for equals () to return false even if contents of two objects are same?

Yes. You can also override the equals() method and play with it.

Why can't we use == to compare String objects?

You should not use == (equality operator) to compare these strings because they compare the reference of the string, i.e. whether they are the same object or not. On the other hand, equals() method compares whether the value of the strings is equal, and not the object itself.

Can you compare objects with ==?

Comparing Objects ¶ When using the comparison operator ( == ), object variables are compared in a simple manner, namely: Two object instances are equal if they have the same attributes and values (values are compared with == ), and are instances of the same class.


2 Answers

A float is only equal to another float, and an int is only equal to another int. The only lines which are returning true are these ones:

Console.WriteLine(f.Equals(i));
Console.WriteLine(i == f);

In both of these cases, there's an implicit conversion of the value of i to float, so they're equivalent to:

Console.WriteLine(f.Equals((float) i));
Console.WriteLine((float) i == f);

These conversions are just normal conversions required for overload resolution of methods and operators.

None of the rest of the lines involve that implicit conversion, so they're comparing the two different types, which gives a result of false even when it is comparing by value (which is the case with all the Equals calls). That's why using Equals on the boxed int values does return true, because that's comparing two values of the same type, by value.

In this case:

Console.WriteLine(obi == obf);

it's not even trying to compare numeric values - it's comparing the references for the boxed objects. As there are two different references, the result is false - and would be even if both values were of type int.

like image 67
Jon Skeet Avatar answered Oct 06 '22 01:10

Jon Skeet


Others have already explained why == does not work as expected on your objects.

Regarding your edit: oi1.Equals(oi2) works because Equals is a virtual function and, thus, Int32.Equals(object) is called, whose return value is defined as follows:

true if obj is an instance of Int32 and equals the value of this instance; otherwise, false.

This also explains why obi.Equals(obf)) returns false: obf is not an instance of Int32.

like image 39
Heinzi Avatar answered Oct 06 '22 01:10

Heinzi