Object equals

T

tshad

I am looking at the object equals methods and am confused.

I was under the impression that o.equals compares content (not whether they
are the same object as o1==o2 does).

But in my example, this doesn't seem to be happening.

If I have a class Account and I create 2 objects with this class exactly the
same way - the content should be equal (I would think).

Here is the code I am running and all the results make sense to me except
the a3.Equals(a4) which should be true.

**************************************
Account a3 = new Account(1000.0, "Count Dracula", 500);
Account a4 = new Account(1000.0, "Count Dracula", 500);

if (a3 == a4)
Console.WriteLine("a3 == a4");
else
Console.WriteLine("a3 != a4");

if (a3.Equals(a4))
Console.WriteLine("a3.Equals(a4)");
else
Console.WriteLine("a3.NotEquals(a4)");

Console.WriteLine("\na3 content:");
a3.Report();
Console.WriteLine("\na4 content:");
a4.Report();


a3 = a4;
if (a3 == a4)
Console.WriteLine("\nAfter a3=a4 a3==a4");
else
Console.WriteLine("\nAfter a3=a4 a3!=a4");
***************************************

The results:
******************************
a3 != a4
a3.NotEquals(a4) <--- Should be equal as the next set shows
content the same

a3 content:
Account Name: Count Dracula
Balance: 1000
Overdraft Limit: 500
Penalty: 25

a4 content:
Account Name: Count Dracula
Balance: 1000
Overdraft Limit: 500
Penalty: 25

After a3=a4 a3==a4
********************************

Why is a3.Equals(a4) showing as not equal?

Thanks,

Tom
 
J

Jon Skeet [C# MVP]

tshad said:
I am looking at the object equals methods and am confused.

I was under the impression that o.equals compares content (not whether they
are the same object as o1==o2 does).

It doesn't do it automatically (for reference types) - but that's what
you should do if you override Equals yourself.

In other words, if you want to be able to compare objects for equality,
you should override Equals and GetHashCode appropriately.
 
P

PvdG42

tshad said:
I am looking at the object equals methods and am confused.

I was under the impression that o.equals compares content (not whether
they are the same object as o1==o2 does).

But in my example, this doesn't seem to be happening.

If I have a class Account and I create 2 objects with this class exactly
the same way - the content should be equal (I would think).

Here is the code I am running and all the results make sense to me except
the a3.Equals(a4) which should be true.

**************************************
Account a3 = new Account(1000.0, "Count Dracula", 500);
Account a4 = new Account(1000.0, "Count Dracula", 500);

if (a3 == a4)
Console.WriteLine("a3 == a4");
else
Console.WriteLine("a3 != a4");

if (a3.Equals(a4))
Console.WriteLine("a3.Equals(a4)");
else
Console.WriteLine("a3.NotEquals(a4)");

Console.WriteLine("\na3 content:");
a3.Report();
Console.WriteLine("\na4 content:");
a4.Report();


a3 = a4;
if (a3 == a4)
Console.WriteLine("\nAfter a3=a4 a3==a4");
else
Console.WriteLine("\nAfter a3=a4 a3!=a4");
***************************************

The results:
******************************
a3 != a4
a3.NotEquals(a4) <--- Should be equal as the next set shows
content the same

a3 content:
Account Name: Count Dracula
Balance: 1000
Overdraft Limit: 500
Penalty: 25

a4 content:
Account Name: Count Dracula
Balance: 1000
Overdraft Limit: 500
Penalty: 25

After a3=a4 a3==a4
********************************

Why is a3.Equals(a4) showing as not equal?

Thanks,

Tom
From the Object class Equals method docs:

<quote>
The default implementation of Equals supports reference equality only, but
derived classes can override this method to support value equality.

For reference types, equality is defined as object equality; that is,
whether the references refer to the same object. For value types, equality
is defined as bitwise equality. The ValueType class supports value types.
</quote>
To get the behavior you seek, you must override the Equals() method in your
class to do a field by field comparison.
 
A

Arne Vajhøj

tshad said:
I am looking at the object equals methods and am confused.

I was under the impression that o.equals compares content (not whether they
are the same object as o1==o2 does).

But in my example, this doesn't seem to be happening.

If I have a class Account and I create 2 objects with this class exactly the
same way - the content should be equal (I would think).

== always compare object identity.

Object equals does the same as ==.

Classes may override equals to to compare content.

Many classes does that - including String.

But it does not happen by magic.

If your Account class need an equals that compare content, then
you need to write the equals method.

Arne
 
A

Arne Vajhøj

Arne said:
== always compare object identity.

Object equals does the same as ==.

Classes may override equals to to compare content.

Many classes does that - including String.

But it does not happen by magic.

If your Account class need an equals that compare content, then
you need to write the equals method.

And that was the Java version.

In C# you can also override the == operator to compare content.

Arne
 
J

Jon Skeet [C# MVP]

And that was the Java version.

(Slightly OT, but may give others here a giggle.)

Pop quiz around Java and equality, using auto-boxing. What does the
following program print on your favourite JVM/compiler combination, and
why?

public class Test
{
public static void main(String[] args)
{
Object o1 = 127;
Object o2 = 127;
System.out.println(o1==o2);

o1 = 128;
o2 = 128;
System.out.println(o1==o2);
}
}
 
R

Rudy Velthuis

tshad said:
I am looking at the object equals methods and am confused.

I was under the impression that o.equals compares content (not
whether they are the same object as o1==o2 does).

But in my example, this doesn't seem to be happening.

If I have a class Account and I create 2 objects with this class
exactly the same way - the content should be equal (I would think).

Whether Equals() returns true or not totally depends on how it is
coded, i.e. what equality means depends on the implementation. There is
no automatic way to compare two items for equality.
 
A

Alun Harford

Jon said:
(Slightly OT, but may give others here a giggle.)

Pop quiz around Java and equality, using auto-boxing. What does the
following program print on your favourite JVM/compiler combination, and
why?

<spoilers + java mini-rant>

Well it doesn't compile on my favourite compiler (ie. Java 1.4.2)

After that, things went downhill.

JVMs are required to ensure that boxed integral values between -128 and
127 refer to the same object. They may (but are not required to) cache
values outside of that range, so the second value printed varies from
JVM to JVM.

This kind of stuff with adding features to the language, despite the
fact that they're clearly broken (autoboxing and generics), is why I
tend to code in C# these days.

Alun Harford
 
T

tshad

Jon Skeet said:
It doesn't do it automatically (for reference types) - but that's what
you should do if you override Equals yourself.

In other words, if you want to be able to compare objects for equality,
you should override Equals and GetHashCode appropriately.

That makes sense.

I just assumed it would compare all the properties in the class to see if
they matched, but as everyone else has said - if I want it to work that way,
I have to override it.

I wasn't sure because I thought I had read that == would compare the
references and .Equals would compare the content. But if I have this right.
Both == and .Equals work the same way out of the box and you can change
either (override them) to do what you want.

So in actuality, there is no difference between the two unless you want to
make it so - if I am reading this right.

Thanks,

Tom
 
J

Jon Skeet [C# MVP]

So in actuality, there is no difference between the two unless you want to
make it so - if I am reading this right.

Well, they will have the same effect for reference types when nothing
is overridden or overloaded. The difference is that you've can't
*override* == you can only *overload* it - whereas if you override
Equals, you get polymorphic behaviour.

As an example, the string type overloads == and overrides Equals. So,
if you take (avoiding string literal interning by using StringBuilder)

string s1 = new StringBuilder("hello").ToString();
string s2 = new StringBuilder("hello").ToString();

s1==s2 - True
s2.Equals(s2) - True

But:

object o1 = s1;
object o2 = s2;

o1==o2 - False; == isn't polymorphic
o1.Equals(o2) - True, Equals is polymorphic

Jon
 
T

tshad

Jon Skeet said:
Well, they will have the same effect for reference types when nothing
is overridden or overloaded. The difference is that you've can't
*override* == you can only *overload* it - whereas if you override
Equals, you get polymorphic behaviour.

But that is really semantics isn't it?

The behavior is the same - just the definition is different and there is
more to polymorphism, but as far as this situation - you are doing the same
thing with the same result.

Overloading or overriding - both are changing the default behavior and you
are getting the same result.

But it probably is better to use the correct terms.

Thanks,

Tom
 
J

Jon Skeet [C# MVP]

But that is really semantics isn't it?

"Semantics" is "the meaning of things" - so dismissing something as
"really semantics" is pointless. They have different meanings, and
that's important.
The behavior is the same - just the definition is different and there is
more to polymorphism, but as far as this situation - you are doing the same
thing with the same result.

No, the behaviour is *not* the same, due to how polymorphism works. My
example showed that you get different results as soon as polymorphism
is involved. That a pretty major difference!
Overloading or overriding - both are changing the default behavior and you
are getting the same result.

You get the same result in some situation and different results in
other situations, as my example showed.
But it probably is better to use the correct terms.

It's *vital* to use the correct terms if you want to communicate
accurately.

Jon
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Top