Ну, проблема (правильная или неправильная) не в EqualityComparer<Uri>.Default
.Он вызывает Uri.Equals()
, как и должно быть.
Теперь Uri.Equals()
игнорирует различия только для одного фрагмента.В очень многих случаях это уместно.Во многих это не так.Лично у меня не было бы этого по умолчанию, но так как я не тот, кто его кодировал, возможно, я не знаю каких-либо веских причин, чтобы все было как есть.
Обратите внимание, что этозадокументировано.
Другие решения также являются дискуссионными (то, что игнорируется различие в регистре компонентов хоста, соответствует многим практическим соображениям относительно URI, но не тому, как в некоторых спецификациях определяется равенство URI).
Если вынужно более строгое равенство, чем это, я предлагаю вам определить свой собственный компаратор:
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();
}
}
Тем не менее, вы можете обнаружить, что в некоторых случаях вышеприведенный случай считается неравным, а также равным.Например, вы должны подумать, одинаковы ли версии punycode и non-punycode, должны ли экранированные символы без специальных символов быть экранированными и т. Д.Метод Ури Compare
может быть полезным в таких случаях.