Re[3]: EqualityComparer<T>.Default
От: Qbit86 Кипр
Дата: 23.06.21 00:01
Оценка:
Здравствуйте, Kolesiki, Вы писали:

K>Нельзя просто за юзера решить "ты хочешь сравнить строки" (вместо адресов).


Поэтому большинство стандартных алгоритмов поиска/сравнения имеют перегрузки, принимающие на вход IEqualityComparer<T>. И только если пользователь игнорирует эти перегрузки, то алгоритмы используют EqualityComparer<T>.Default.

K>Это не говоря о том, что даже само сравнение может быть ещё и case insensitive.


Да, поэтому многие code style guide'ы и статические анализаторы предписывают явно задавать стратегию сравнения строк.

BCL предоставляет готовую пачку экземпляров компараторов строк StringComparer (реализующего IEqualityComparer<string?>) под разные нужды:
• StringComparer.Ordinal,
• StringComparer.InvariantCultureIgnoreCase, etc.
Их и нужно передавать в алгоритмы типа Dictionary<string, TValue>, Linq, etc.
И соответственно собственный библиотечный код пишут терминах IEqualityComparer<T>.

Прикладной же код может использовать для сравнения статические функции с третьим параметром — стратегией StringComparison:
• string.Equals(s1, s2, StringComparison.Ordinal),
• string.Equals(s1, s2, StringComparison.InvariantCultureIgnoreCase), etc.

Чего не нужно использовать для сравнения строк ни библиотечному, ни прикладному коду — operator ==() или экземплярный метод string.Equals().

K>Нельзя просто за юзера решить "ты хочешь сравнить строки" (вместо адресов).


Тебе нужно явно передать ReferenceEqualityComparer.Instance:

An IEqualityComparer{Object} that uses reference equality (object.ReferenceEquals(object?, object?)) instead of value equality (object.Equals(object?)) when comparing two object instances.
/ReferenceEqualityComparer.cs

А для поиска использовать List<T>.FindIndex(). Правда, он получает на вход Predicate<string>, а не IEqualityCmparer<T>, но это тривиально оборачивается лямбдой.

Да, здесь уже нужно учитывать, что литералы интернируются.
Но закладываться в логике на сравнение по ссылке вместо сравнения по значению — это в принципе какой-то супер-специфичный сценарий. «Так не носят.» В исходниках BCL этот ReferenceEqualityComparer почти не используется.
Глаза у меня добрые, но рубашка — смирительная!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.