Как сравнить строки — ==, Equals и без учёта регистра
string a = "Привет";
string b = "привет";
Console.WriteLine(a == b);
Console.WriteLine(a.Equals(b));
Console.WriteLine(a.Equals(b, StringComparison.OrdinalIgnoreCase));
Console.WriteLine(string.Equals(a, b, StringComparison.CurrentCultureIgnoreCase));False
False
True
True==иEqualsсравнивают строки по содержимому, символ за символом, и учитывают регистр:Пип— разные символы.- Без учёта регистра —
EqualsсStringComparison.OrdinalIgnoreCase(илиCurrentCultureIgnoreCase).
В C# == для строк сравнивает текст, а не адреса в памяти, как в Java. Писать a.Equals(b) вместо a == b ради «правильности» не нужно.
Ответ пользователя: «да», «Да», «ДА»
Ввод с клавиатуры удобно сравнивать без учёта регистра и без лишних пробелов по краям:
Console.Write("Продолжить? ");
string answer = (Console.ReadLine() ?? "").Trim();
if (answer.Equals("да", StringComparison.OrdinalIgnoreCase))
{
Console.WriteLine("Продолжаем");
}
else
{
Console.WriteLine("Стоп");
}Часто пишут и answer.ToLower() == "да" — это работает, но создаёт лишнюю строку. Вариант с StringComparison точнее и быстрее.
Какая строка раньше по алфавиту
string.Compare(a, b) и a.CompareTo(b) возвращают число: меньше нуля — a раньше, ноль — равны, больше нуля — a позже. Само значение может быть любым, поэтому сравнивайте его с нулём, а не с −1 или 1:
Console.WriteLine(string.Compare("арбуз", "банан") < 0);
Console.WriteLine("кот".CompareTo("кот") == 0);
Console.WriteLine(string.Compare("Яблоко", "яблоко", StringComparison.OrdinalIgnoreCase) == 0);True
True
TrueСортировка массива строк по алфавиту — Array.Sort(words), списка — list.Sort(); без учёта регистра — Array.Sort(words, StringComparer.OrdinalIgnoreCase).
Ordinal или культура
Культура в .NET — правила языка и страны: порядок букв, большие и маленькие буквы, запись чисел и дат. Ordinal — сравнение просто по кодам символов, без этих правил.
| Способ | Как сравнивает | Когда брать |
|---|---|---|
Ordinal, OrdinalIgnoreCase | по кодам символов | команды, имена файлов, ключи настроек, ответы «да/нет» |
CurrentCulture, CurrentCultureIgnoreCase | по правилам языка из настроек компьютера | сортировка слов для показа человеку |
InvariantCulture | по правилам, не зависящим от настроек | одинаковый порядок на любом компьютере |
Разница видна на буквах вроде ё: по кодам она идёт после я, а по правилам языка — рядом с е.
Подводные камни
- Методы с разным поведением по умолчанию.
==,EqualsиContainsсравнивают по кодам символов (Ordinal), аCompareTo,string.Compare,StartsWith,EndsWithиIndexOfсо строкой — по правилам культуры. Когда важна точность, передавайте способ явно:s.StartsWith("abc", StringComparison.Ordinal). - В .NET 5 и новее культурный поиск иногда ведёт себя неожиданно со служебными символами: например,
"a\r\nb".IndexOf("\n")может вернуть −1. Для таких поисков беритеIndexOf('\n')(символ, а не строку) илиStringComparison.Ordinal. a.Equals(b)упадёт сNullReferenceException, еслиa—null.a == bиstring.Equals(a, b)сnullработают без ошибок.