Can someone explain this to me?

  • Thread starter Peter Morris [Droopy eyes software]
  • Start date
P

Peter Morris [Droopy eyes software]

object a = 5;
object b = 5;
if (a != b)
throw new InvalidOperationException("a != b");

Why is the exception thrown? I guessed it is something to do with boxing
because the following does not throw an exception

object a = 5;
object b = 5;
if (!a.Equals(b))
throw new InvalidOperationException("a != b");

but why doesn't the boxed object use the Equals method of the object it
contains?
 
N

Nicholas Paldino [.NET/C# MVP]

Peter,

The reason that it throws in the first one is that you are performing a
reference comparison. The boxing has created two separate objects on the
heap which have the same boxed value.

In the second example, the implementation of Equals must check the
values in the boxed values (as opposed to ==/!=).

Hope this helps.
 
J

John Duval

Peter said:
object a = 5;
object b = 5;
if (a != b)
throw new InvalidOperationException("a != b");

Why is the exception thrown? I guessed it is something to do with boxing
because the following does not throw an exception

object a = 5;
object b = 5;
if (!a.Equals(b))
throw new InvalidOperationException("a != b");

but why doesn't the boxed object use the Equals method of the object it
contains?

In the first example, the code is checking to see if the object
references are the same (i.e. do the variables refer to the same
object?), which they are not. In the second example, the code is
checking to see if the object values are the same, which they are.

John
 
J

Jon Skeet [C# MVP]

Peter Morris said:
object a = 5;
object b = 5;
if (a != b)
throw new InvalidOperationException("a != b");

Why is the exception thrown? I guessed it is something to do with boxing
because the following does not throw an exception

object a = 5;
object b = 5;
if (!a.Equals(b))
throw new InvalidOperationException("a != b");

but why doesn't the boxed object use the Equals method of the object it
contains?

Unless it is overloaded, the == operator just compares object
references for reference types. Here, you've got references to two
different objects, so a != b. However, they have value equality, so
a.Equals(b).
 
E

Edward Diener

Peter said:
object a = 5;
object b = 5;
if (a != b)
throw new InvalidOperationException("a != b");

Why is the exception thrown?

The object references are checked.
I guessed it is something to do with boxing
because the following does not throw an exception

object a = 5;
object b = 5;
if (!a.Equals(b))
throw new InvalidOperationException("a != b");

The object values are checked.
 
S

Siva M

The first comparison performs reference comparison (two distinct objects
with same value underneath) whereas the second one forces a value comarison.

message object a = 5;
object b = 5;
if (a != b)
throw new InvalidOperationException("a != b");

Why is the exception thrown? I guessed it is something to do with boxing
because the following does not throw an exception

object a = 5;
object b = 5;
if (!a.Equals(b))
throw new InvalidOperationException("a != b");

but why doesn't the boxed object use the Equals method of the object it
contains?
 
P

Peter Morris [Droopy eyes software]

Unless it is overloaded, the == operator just compares object
references for reference types

But the dotnet way of comparing objects for new class types is to override
Equals right? So why doesn't == use Equals?

5 == (4 + 1) are not the same object reference, so surely the == is using
5.Equals(4 + 1)?
 
J

Jon Skeet [C# MVP]

Peter Morris said:
But the dotnet way of comparing objects for new class types is to override
Equals right?

If you call Equals, yes.
So why doesn't == use Equals?

Because == (unless it's overloaded) just compares references. The ==
operator is overloaded for some but far from all types.
5 == (4 + 1) are not the same object reference, so surely the == is using
5.Equals(4 + 1)?

No, because the == operator isn't overloaded on the boxed Int32 type.
 
P

Peter Morris [Droopy eyes software]

I'm not impressed at all to be honest. To implement "Equals" I have to do
two things?

1) Implement Equals
2) Override ==

I really don't like it. Two things are either equal or they are not. It
makes no sense to say A equals B but B does not equal A, and along these
lines I therefore state that A == B should always return the same as
A.Equals(B)

At the moment it's a bit too much like a human response:

Question: Does A equal B?
Answer: It depends who you ask
 
J

Jon Skeet [C# MVP]

Peter said:
I'm not impressed at all to be honest. To implement "Equals" I have to do
two things?

1) Implement Equals
2) Override ==

No. To implement Equals, you just have to implement Equals.

If you want to make it so that clients get value equality from ==
rather than reference equality, you also need to overload (not
override) ==. They're different things, and it often makes sense to do
one but not the other.
I really don't like it. Two things are either equal or they are not.

No - two references are either unrelated, refer to equal objects, or
refer to the same object.
It makes no sense to say A equals B but B does not equal A, and along these
lines I therefore state that A == B should always return the same as
A.Equals(B)

The problem is that A and B are references. A.Equals(B) is asking
whether the objects referred to by A and B are equal. A==B is (usually)
asking whether A and B are equal *in themselves*.
At the moment it's a bit too much like a human response:

Question: Does A equal B?
Answer: It depends who you ask

Suppose I go to see a production of "Sunday in the Park with George" in
London. (I wish I had the time...) Now suppose a friend of mine sees a
production of "Sunday in the Park with George" in Broadway.

Did we see the same show? Well, sort of - it was the same musical, but
different productions. (You could take the analogy further - what about
if we both saw it in London, but on different nights?)

Whether you like the behaviour or not, that *is* the behaviour of
C#/.NET.

Jon
 
P

Peter Morris [Droopy eyes software]

Did we see the same show? Well, sort of - it was the same musical, but
different productions. (You could take the analogy further - what about
if we both saw it in London, but on different nights?)


But once you have decided whether or not you saw the same show I should get
the same answer no matter how I ask the question.

Sure it is the default behaviour of C# but that doesn't mean I have to like
it or think it is correct, but I do have to keep it in mind! Whenever
passing "object" as a parameter I should use Equals.


Thanks

Pete
 
J

Jon Skeet [C# MVP]

Peter said:
But once you have decided whether or not you saw the same show I should get
the same answer no matter how I ask the question.

No - if you ask "Did we see the same musical" it would be reasonable to
say "Yes". If you ask "Did we see the same performance" it would be
reasonable to say "No". Here, a performance is a sort of reference to
an instance of a production - two performances can be of the same
musical, but be different performances.
Sure it is the default behaviour of C# but that doesn't mean I have to like
it or think it is correct, but I do have to keep it in mind! Whenever
passing "object" as a parameter I should use Equals.

Assuming you want value equality rather than reference equality, yes.

Jon
 
K

Kevin Spencer

This all reminds me of an old joke:

"No, no, Sally, I said 'All men are created equal,' NOT 'all men are made
the same!'

--
HTH,

Kevin Spencer
Microsoft MVP
Chicken Salad Surgery

Expect the unaccepted.
 

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

Top