Ответ
Сравнение строк в C# — нетривиальная задача из-за различий в регистре, культуре и способе хранения. Важно выбирать правильный метод сравнения для конкретного сценария.
Основные методы и операторы:
| Метод/Оператор | Описание | Рекомендуется для |
|---|---|---|
== / != операторы |
Сравнивают содержимое строк (не ссылки). Используют StringComparison.Ordinal по умолчанию в коде, но могут зависеть от контекста. |
Простых сравнений, когда важна точная последовательность символов. |
string.Equals(a, b) |
Статический метод с перегрузками для указания типа сравнения. Самый явный и рекомендуемый способ. | Любых сценариев, особенно с указанием StringComparison. |
string.Compare(a, b) |
Возвращает целое число (<0, 0, >0), указывающее на лексикографический порядок. Полезно для сортировки. |
Сортировки и упорядочивания строк. |
a.CompareTo(b) |
Экземплярный метод с той же логикой, что и string.Compare. |
Ключевой параметр: StringComparison
string str1 = "Hello";
string str2 = "hello";
string str3 = "HELLO";
// 1. Ordinal (по умолчанию для == в коде): Быстрое, бинарное сравнение кодов символов. Без учета культуры.
bool isEqualOrdinal = string.Equals(str1, str2, StringComparison.Ordinal); // false
// 2. OrdinalIgnoreCase: Быстрое сравнение без учета регистра. Идеально для идентификаторов, путей, URL.
bool isEqualOrdinalIgnore = string.Equals(str1, str2, StringComparison.OrdinalIgnoreCase); // true
// 3. CurrentCulture / InvariantCulture: Учитывает правила языка и региональных параметров (например, "ss" и "ß" в немецком). Медленнее.
// Используется для отображения пользователю.
bool isEqualCulture = string.Equals("straße", "strasse", StringComparison.CurrentCulture); // Может быть true в зависимости от культуры.
// 4. CurrentCultureIgnoreCase / InvariantCultureIgnoreCase
bool isEqualCultureIgnore = string.Equals(str1, str3, StringComparison.CurrentCultureIgnoreCase); // true
Правила выбора:
- Для внутренних идентификаторов, путей, настроек, сравнения в словарях (
Dictionary<string, ...>) — используйтеStringComparison.OrdinalилиOrdinalIgnoreCase. Это самое быстрое и безопасное. - Для данных, отображаемых пользователю (сортировка, поиск в UI) — используйте
CurrentCultureилиInvariantCulture. - Никогда не используйте методы без параметра
StringComparison(например,str1.Equals(str2)) для важных сравнений, так как по умолчанию они зависят от текущей культуры системы.
Ответ 18+ 🔞
Слушай, ну вот смотри, все эти ваши сравнения строк в C# — это ж целая наука, блядь. Казалось бы, что там сравнивать? Две строки, ну сравнил и всё. Ан нет, сука, тут столько подводных камней, что просто пиздец. Регистр, культура, производительность — овердохуища нюансов.
Основные штуки, которыми ты можешь тыкать:
| Метод/Оператор | Что делает | Когда юзать |
|---|---|---|
== / != |
Сравнивает содержимое, а не ссылки. Но тут есть прикол — в коде он обычно использует Ordinal, но полагаться на это как на манну небесную не стоит. |
Для простых проверок, когда тебе похуй на культуру и нужна точная последовательность символов. |
string.Equals(a, b) |
Статический метод, самый чёткий. Тут можно явно указать, как сравнивать. | Почти всегда, особенно когда хочешь явно прописать StringComparison и не париться. |
string.Compare(a, b) |
Возвращает циферку: меньше нуля, ноль, больше нуля. Полезно, когда надо не просто проверить равенство, а понять, какая строка "больше" для сортировки. | Для сортировки или упорядочивания, когда надо знать порядок. |
a.CompareTo(b) |
Почти то же самое, что и Compare, но вызывается от самой строки. |
А теперь самое сокровенное: параметр StringComparison
Вот смотри, в чём вся соль:
string str1 = "Hello";
string str2 = "hello";
string str3 = "HELLO";
// 1. Ordinal (часто стоит по умолчанию): Тупо сравнивает коды символов. Быстро, как угорелый, но без мозгов. Культуру не уважает.
bool isEqualOrdinal = string.Equals(str1, str2, StringComparison.Ordinal); // false — потому что 'H' и 'h' разные символы, ёпта!
// 2. OrdinalIgnoreCase: Тоже быстро, но регистр забивает хуй. Идеально для всяких внутренних штук — путей файлов, ключей в настройках, URL.
bool isEqualOrdinalIgnore = string.Equals(str1, str2, StringComparison.OrdinalIgnoreCase); // true — теперь похуй на регистр.
// 3. CurrentCulture / InvariantCulture: Вот тут уже включаются мозги и правила языка. Например, в немецком "ß" и "ss" могут считаться одинаковыми. Медленнее, конечно.
// Используй, когда работаешь с тем, что видит юзер.
bool isEqualCulture = string.Equals("straße", "strasse", StringComparison.CurrentCulture); // Может быть true, смотря какая культура на системе.
// 4. CurrentCultureIgnoreCase / InvariantCultureIgnoreCase
bool isEqualCultureIgnore = string.Equals(str1, str3, StringComparison.CurrentCultureIgnoreCase); // true — регистр игнорируется по правилам культуры.
Итак, золотые правила, чтобы не облажаться:
- Всё, что внутри системы (ключи словарей, имена файлов, настройки, константы) — юзай
StringComparison.OrdinalилиOrdinalIgnoreCase. Быстро и без сюрпризов, ебать. - Всё, что для глаз пользователя (сортировка в интерфейсе, поиск по введённому тексту) — тогда уже
CurrentCultureилиInvariantCulture. Чтобы всё было культурно и по правилам языка. - И самое главное, запомни как "Отче наш": Никогда, блядь, просто так не вызывай методы вроде
str1.Equals(str2)без указанияStringComparison. Они по умолчанию смотрят на культуру системы, а это — прямой путь в ад с неочевидными багами, когда у тебя на компе одно, а на сервере другое. Я серьёзно, чувак, доверия к этому ноль ебать. Всегда указывай явно, как сравнивать.