С# Различия между оператором ==, 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)
, почему он дает два разных результата?
Ответы
Ответ 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.
Остальная часть проверок, которые вы делаете, сравнивает ссылку.