Charles Lambert
Charles Lambert

Reputation: 5132

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

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

Upvotes: 7

Views: 2552

Answers (8)

Jeb
Jeb

Reputation: 3799

To understand more about what happens when you box value types, Shivprasad describes this quite succinctly here:

Boxing and Unboxing

Since you are boxing the value types to objects, you are now performing reference equality. Since they now reside at different memory locations in your example, will return false.

Upvotes: 2

sll
sll

Reputation: 62504

When you've declared two objects they references a different memory location:

object obf = f;         // this simplified as new float(f)
object obi = i;         // this simplified as new int(i)

but try out following, let one object to reference an other:

obf = obi;
Console.WriteLine(obf.Equals(obi));

MSDN, Object.Equals Method

The default implementation of Equals supports reference equality for reference types, and bitwise equality for value types. Reference equality means the object references that are compared refer to the same object. Bitwise equality means the objects that are compared have the same binary representation.

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1500635

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.

Upvotes: 9

Heinzi
Heinzi

Reputation: 172270

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.

Upvotes: 3

andreapier
andreapier

Reputation: 2958

Because they are assigned to different memeory cells. 2 objects are = only when they are the same object. In the float and int part you get a true when you test the 2 variables because the runtime checks their value. that's all!

Upvotes: 0

Polynomial
Polynomial

Reputation: 28316

You're boxing the int and float to an object, which means they're compared as references. Since they're not references to the same object, they're not equal.

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

Upvotes: 2

Davide Piras
Davide Piras

Reputation: 44605

Because Equals compares the address of the object reference and the two numbers are stored in different locations. if you compare the two value types Equals behaves correctly as it has been overridden for float, int, string and other types.

Upvotes: 0

Mranz
Mranz

Reputation: 1277

When you cast a value type to object, it is actually getting put in the heap and == compares references at that point, which will be false. (Simplified)

Upvotes: 0

Related Questions