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

Как перегружен оператор == в классе String?

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

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

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

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

Перегрузка оператора == в классе String

Оператор == в классе System.String перегружен (overloaded) для сравнения не по ссылке, а по значению. Это одно из важнейших отличий string от большинства других ссылочных типов в C#.

Как это реализовано

В классе String перегружены оба оператора равенства (== и !=). Реализация делегирует вызов статическому методу string.Equals(string, string), который в свою очередь использует внутренний метод сравнения с учетом регистра (по умолчанию для текущей культуры).

Ключевой момент: Компилятор C# и среда выполнения .NET обрабатывают строки особенно:

  • Для литералов применяется интернирование строк (string interning)
  • Перегрузка оператора == обеспечивает семантику сравнения по значению

Пример кода

string s1 = "Hello";
string s2 = "Hello";
string s3 = new string('H', 1) + "ello"; // Создание новой строки в куче

Console.WriteLine(s1 == s2); // True - сравнение по значению
Console.WriteLine(s1 == s3); // True - значения одинаковые
Console.WriteLine(object.ReferenceEquals(s1, s2)); // True - интернирование
Console.WriteLine(object.ReferenceEquals(s1, s3)); // False - разные объекты

string s4 = "HELLO";
Console.WriteLine(s1 == s4); // False - регистр имеет значение
Console.WriteLine(s1.Equals(s4, StringComparison.OrdinalIgnoreCase)); // True

Отличие от Object.Equals

Важно понимать разницу:

  • == для string перегружен и сравнивает значения
  • object.ReferenceEquals() всегда сравнивает ссылки
  • string.Equals() также сравнивает значения, но имеет больше вариантов сравнения
string a = "test";
string b = new string("test".ToCharArray());

// Разные результаты для оператора == и ReferenceEquals
Console.WriteLine(a == b); // True
Console.WriteLine(object.ReferenceEquals(a, b)); // False

Поведение при сравнении с null

Перегруженный оператор == корректно обрабатывает сравнение с null:

string s1 = null;
string s2 = "text";

Console.WriteLine(s1 == s2); // False
Console.WriteLine(s1 == null); // True
Console.WriteLine(s2 == null); // False

Особенности в разных контекстах

  1. Сравнение в switch-выражениях

    string value = "test";
    switch (value)
    {
        case "test": // Используется сравнение через ==
            Console.WriteLine("Found!");
            break;
    }
    
  2. Использование в словарях Словари (Dictionary) используют Equals и GetHashCode для сравнения ключей, что согласовано с поведением ==.

  3. Сравнение с интернированием

    string s1 = "cat";
    string s2 = String.Intern("cat");
    Console.WriteLine(s1 == s2); // True
    Console.WriteLine(object.ReferenceEquals(s1, s2)); // True
    

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

Лучшие практики:

  1. Для сравнения строк используйте явные методы сравнения когда нужен контроль над культурой:

    // Для чувствительности к культуре
    string.Equals(str1, str2, StringComparison.CurrentCulture);
    
    // Для ординарного сравнения (быстрее)
    string.Equals(str1, str2, StringComparison.Ordinal);
    
  2. При сравнении без учета регистра используйте StringComparison.OrdinalIgnoreCase для производительности:

    if (str1.Equals(str2, StringComparison.OrdinalIgnoreCase))
    {
        // Действие
    }
    
  3. Оператор == удобен для читаемости кода, когда достаточно сравнения с учетом текущей культуры.

Внутренняя реализация

На уровне IL-кода оператор == преобразуется в вызов ceq для сравнения ссылок для большинства типов, но для строк компилятор генерирует вызов перегруженного оператора, который в итоге вызывает внутренний метод string.Equals.

Важное следствие: Перегрузка оператора == делает поведение строк интуитивно понятным для разработчиков, но важно помнить, что это исключение из общего правила работы с ссылочными типами. Для собственных классов разработчик должен самостоятельно перегружать операторы равенства, если требуется подобное поведение.

Как перегружен оператор == в классе String? | PrepBro