Подтвердить что ты не робот

С# Различия между оператором ==, StringBuilder.Equals, Object.Equals и Object.ReferenceEquals

У меня вопрос о Object.Equals и Equals(object). Мой пример кода ниже:

class Program
{
    static void Main(string[] args)
    {
        var sb1 = new StringBuilder("Food");
        var sb2 = new StringBuilder("Food");
        Console.WriteLine(sb1 == sb2);
        Console.WriteLine(sb1.Equals(sb2));
        Console.WriteLine(Object.Equals(sb1, sb2));
        Console.WriteLine(Object.ReferenceEquals(sb1, sb2));
        Console.ReadLine();
    }
}

Вывод:

False
True
False
False

Но насколько мне известно Object.Equals(sb1, sb2) внутренне вызывает sb1.Equals(sb2), почему он дает два разных результата?

4b9b3361

Ответ 1

Вам не хватает другого теста:

Console.WriteLine(sb1.Equals((object)sb2)); // False!

StringBuilder не переопределяет Equals(object), он перегружает его другим Equals(StringBuilder).

Object.Equals(object, object) вызывает Equals(object), поэтому результат равен false.

Ответ 2

Вы используете 4 разных метода сравнения, приводят к различным результатам:

  • Оператор == будет по умолчанию проверять, равны ли ссылки. В этом случае у вас есть два экземпляра, поэтому они имеют две разные ссылки. Поведение == может быть переопределено любым типом (например, string имеет свой собственный метод сравнения), но в случае StringBuilder это не так.
  • Метод StringBuilder.Equals(StringBuilder) будет сравнивать с другим StringBuilder и сравнивает некоторые внутренние значения. Эти значения в вашем случае одинаковы. Странно то, что StringBuilder не переопределяет метод StringBuilder.Equals(object) для применения той же логики.
  • Метод object.Equals(object, object) попытается вызвать метод .Equals(object) одного из объектов. В этом случае: StringBuilder.Equals(object), который, как я уже говорил, не имел логики для сравнения значений. Результатом является просто сравнение ссылок обоих экземпляров.
  • Object.ReferenceEquals будет просто сравнивать ссылки.

Для получения дополнительной информации см.:

Ответ 3

StringBuilder.equals не сравнивает объекты, а от MSDN:

"Истинно, если этот экземпляр и sb имеют равную строку, Емкостьи MaxCapacity; в противном случае - false.

Остальная часть проверок, которые вы делаете, сравнивает ссылку.