Inconsistent behavior in Uri class (Equals vs. ==)

  • Thread starter Thread starter Tom Cabanski
  • Start date Start date
T

Tom Cabanski

We have found that the Equals method of the Uri class
works as expected but that the "==" operator does not.
For example, here's a little console application:

using System;

namespace UriEqualsBug
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
Uri u1 = new Uri
("http://tom/foo.xml");
Uri u2 = new Uri
("http://tom/foo.xml");
Console.WriteLine("The two
instances are equal using the equals method {0}",
u1.Equals(u2));
Console.WriteLine("The two
instances are equal using the == operator {0}", u1 == u2);

}
}
}

One would expect the output to be true for both
comparisons. However, we get true from the u1.Equals(u2)
and false from u1 == u2. Any ideas? Is this a framework
bug?

We are using the .NET framework 1.1.4322.
 
Tom Cabanski said:
We have found that the Equals method of the Uri class
works as expected but that the "==" operator does not.

Basically, Uri doesn't override the == operator, but does override
Equals. This doesn't necessarily violate the framework suggestion,
which is:

<quote>
Most reference types must not overload the equality operator, even if
they override Equals. However, if you are implementing a reference type
that is intended to have value semantics, such as a complex number
type, you must override the equality operator.
</quote>

Now, I don't know whether you'd say that Uri is "intended to have value
semantics" or not - but if not, the above seems fine with the idea of
Uri overriding Equals but not ==.
 
That's the correct behavior. == tells you (unless overridden) whether or
not two objects are literally the same (their memory location is the same),
whereas .Equals() determines whether or not two objects fit some equality
definition. == returns false because you are comparing two separate
instances, living in separate areas of memory. .Equals returns true because
their URIs are equal. In Java (I haven't checked this in .Net, but it
really isn't something I'm dying to know), == on the string literal URIs
will return true, though, as literals are assigned from a single pool of
memory; I'm pretty sure .Net works this way, too, based on working on that
assumption a few times.
 
Keith Patrick said:
That's the correct behavior. == tells you (unless overridden) whether or
not two objects are literally the same (their memory location is the same),
whereas .Equals() determines whether or not two objects fit some equality
definition. == returns false because you are comparing two separate
instances, living in separate areas of memory. .Equals returns true because
their URIs are equal. In Java (I haven't checked this in .Net, but it
really isn't something I'm dying to know), == on the string literal URIs
will return true, though, as literals are assigned from a single pool of
memory; I'm pretty sure .Net works this way, too, based on working on that
assumption a few times.

..NET works that way as well, but it's less important in .NET anyway as
== is overridden for string anyway.
 
-----Original Message-----
That's the correct behavior. == tells you (unless overridden) whether or
not two objects are literally the same (their memory location is the same),
whereas .Equals() determines whether or not two objects
fit some equality

Hmmm. The string's equal operator works in the way one
would expect; it doesn't test the memory address but
rather does a string comparison. So, in my little
example, u1.ToString() == u2.ToString returns true. I
guess that this is because it is intended to have value
semantics as suggested in Jon Skeet's quote (I assume
from somewhere in the framework documentation but he
doesn't attribute it).

Anyway, I can certainly see Uri is setup in the way you
guys are saying. I can't say it's very useful the way it
is and I would argue that it fits the "has value
semantics" test and that's why I was stupid enough to
think that it would have its == operator overloaded.

Ironically, we ran into this in some unit test code that
tests overloaded == operators on things that have value
semantics. Another developer on the team wrote the test
and just couldn't see why it was failing so he brought it
to me. jeez.

I would appreciate knowing the source of Jon's quote.

Thanks for the info guys.
 
Back
Top