← Назад к вопросам

Как происходит сравнение String?

2.3 Middle🔥 161 комментариев
#Основы C# и .NET

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Сравнение строк в C#

Сравнение строк в C# — фундаментальная операция, которая имеет несколько вариантов реализации с различной семантикой и производительностью. Понимание этих различий критически важно для написания корректного и эффективного кода.

Основные способы сравнения строк

1. Операторы == и !=

Наиболее простой и часто используемый способ сравнения строк на равенство.

string str1 = "Hello";
string str2 = "Hello";
string str3 = "HELLO";

bool result1 = (str1 == str2); // true
bool result2 = (str1 == str3); // false

Важно: Для строк оператор == сравнивает значения (содержимое), а не ссылки, благодаря перегрузке оператора в классе String. Это отличается от поведения по умолчанию для reference types.

2. Метод Equals()

Более формальный способ сравнения с возможностью указания типа сравнения.

string str1 = "Hello";
string str2 = "hello";

// Сравнение с учетом культуры и регистра (по умолчанию)
bool result1 = str1.Equals(str2); // false

// Сравнение без учета регистра
bool result2 = str1.Equals(str2, StringComparison.OrdinalIgnoreCase); // true

// Статический метод
bool result3 = String.Equals(str1, str2, StringComparison.CurrentCultureIgnoreCase);

3. Метод Compare() и CompareTo()

Используются для определения порядка строк (лексикографического сравнения).

string str1 = "Apple";
string str2 = "Banana";

int result1 = str1.CompareTo(str2); // отрицательное число (-1)
int result2 = String.Compare(str1, str2); // -1
int result3 = String.Compare(str1, str2, StringComparison.OrdinalIgnoreCase); // -1

Метод возвращает:

  • 0 — строки равны
  • Отрицательное число — первая строка меньше второй
  • Положительное число — первая строка больше второй

Типы сравнения (StringComparison)

Ключевой аспект сравнения строк — выбор правильного типа сравнения через перечисление StringComparison:

  • Ordinal — бинарное сравнение по кодовым точкам Unicode. Быстрее всего, но не учитывает культурные особенности.
  • OrdinalIgnoreCase — бинарное сравнение без учета регистра. Оптимально для внутренних идентификаторов.
  • CurrentCulture / InvariantCulture — сравнение с учетом правил конкретной или инвариантной культуры.
  • CurrentCultureIgnoreCase / InvariantCultureIgnoreCase — сравнение с учетом культуры, но без учета регистра.
string str1 = "straße";
string str2 = "strasse";

bool ordinalResult = str1.Equals(str2, StringComparison.Ordinal); // false
bool cultureResult = str1.Equals(str2, StringComparison.CurrentCulture); // может быть true в немецкой культуре

Особенности и рекомендации

Интернирование строк (String Interning)

C# автоматически интернирует строковые литералы, что может влиять на сравнение ссылок:

string str1 = "Hello";
string str2 = "Hello";
string str3 = new string("Hello".ToCharArray());

bool refEquals1 = object.ReferenceEquals(str1, str2); // true (интернирование)
bool refEquals2 = object.ReferenceEquals(str1, str3); // false (разные объекты)
bool valueEquals = (str1 == str3); // true (значения равны)

Рекомендации по производительности и безопасности

  1. Для чувствительных к безопасности операций (пароли, ключи) всегда используйте Ordinal или OrdinalIgnoreCase
  2. Для сортировки и отображения пользователю используйте CurrentCulture
  3. Для внутренних идентификаторов и путей файловOrdinalIgnoreCase
  4. Избегайте сравнения без явного указания StringComparison в публичных API

Метод ReferenceEquals()

Для сравнения именно ссылок (а не значений) используйте:

string str1 = "Hello";
string str2 = "Hello";
string str3 = new string("Hello".ToCharArray());

bool result1 = object.ReferenceEquals(str1, str2); // true
bool result2 = object.ReferenceEquals(str1, str3); // false

Практический пример выбора типа сравнения

public class StringComparisonExample
{
    public bool ValidatePassword(string input, string expected)
    {
        // Для паролей — строгое бинарное сравнение
        return string.Equals(input, expected, StringComparison.Ordinal);
    }
    
    public bool CompareDisplayNames(string name1, string name2)
    {
        // Для имен пользователей — с учетом культуры, но без регистра
        return string.Equals(name1, name2, StringComparison.CurrentCultureIgnoreCase);
    }
    
    public int SortIdentifiers(string id1, string id2)
    {
        // Для внутренних идентификаторов — быстрое бинарное сравнение
        return string.Compare(id1, id2, StringComparison.OrdinalIgnoreCase);
    }
}

Итог: Сравнение строк в C# — не тривиальная операция. Выбор правильного метода сравнения зависит от контекста: требуется ли учет культуры, важен ли регистр, является ли сравнение чувствительным к безопасности. Всегда явно указывайте StringComparison для избежания неявного поведения и потенциальных уязвимостей.

Как происходит сравнение String? | PrepBro