Is there an explanation for this other than being a bug in the .NET Framework? The EqualityComparer<Uri>.Default.Equals()
method is saying that the following URLs are equal!
and
Notice the space followed by 's' at the end of the first one.
Well, the concern (whether right or wrong) isn't in EqualityComparer<Uri>.Default
. It calls into Uri.Equals()
as it should.
Now, Uri.Equals()
ignores differences on fragment alone. In a great many cases that is appropriate. In a great many it's not. Personally I wouldn't have had it as the default, but then since I'm not someone who coded it perhaps I don't know of some compelling reasons to have things as they are.
Note that this is documented.
Other decisions are also debatable (that it ignores case-difference on host components matches many practical concerns about URIs, but not how URI equality is defined in some specifications).
If you need a stricter equality than that, I suggest you define your own comparator:
public class UriStictEqualityComparer : IEqualityComparer<Uri>
{
public bool Equals(Uri x, Uri y)
{
return ReferenceEquals(x, y)
||
(
x != null
&&
y != null
&&
x.IsAbsoluteUri == y.IsAbsoluteUri
&&
x.ToString() == y.ToString()
);
}
public int GetHashCode(Uri obj)
{
return obj == null ? 0 : obj.ToString().GetHashCode();
}
}
Still, you may find that you want some cases the above considers unequal, to be equal too. E.g. you need to consider whether punycode and non-punycode versions are the same, whether escaped non-special characters should be unescaped, and so on. Uri's Compare
method can be a benefit in such cases.