Почему object.Equals и instanceobject.Equals не совпадают - PullRequest
8 голосов
/ 19 марта 2012
        string s1 = "t";
        string s2 = 't'.ToString();        

        Console.WriteLine(s1.Equals(s2)); // returning true
        Console.WriteLine(object.Equals(s1, s2)); // returning true

Здесь возвращается тот же результат. Теперь, когда я использую StringBuilder, он не возвращает одно и то же значение. В чем причина?

        StringBuilder s1 = new StringBuilder();
        StringBuilder s2 = new StringBuilder();

        Console.WriteLine(s1.Equals(s2)); // returning true
        Console.WriteLine(object.Equals(s1, s2)); // returning false

Edit1 : на мой вопрос ответили ниже. Но во время этого обсуждения выясняется, что StringBuilder не имеет метода переопределения Equals в своей реализации. Поэтому, когда мы вызываем StringBuilder.Equals, он фактически переходит в Object.Equals. Поэтому, если кто-то вызывает StringBuilder.Equals и S1.Equals (S2), результат будет другим.

Ответы [ 3 ]

7 голосов
/ 19 марта 2012

String.Equals () переопределяется в C #, так что идентичные строки фактически Equal(), когда используется переопределение Equal(), определенное в string.

Если высравниваются строковые литералы (в вашем примере это не так), стоит отметить, что идентичные строковые литералы интернированы ... то есть одинаковые строки живут по одному и тому же адресу, поэтомубыть равным по ссылке (например, object.Equals () или s1.ReferenceEquals (s2)), а также по значению.

StringBuilder обеспечивает перегрузку Equals(), которая принимает StringBuilder в качестве параметра (то есть s1.Equals(s2) вызовет эту перегрузку вместо вызова object.Equals(object obj)).

http://msdn.microsoft.com/en-us/library/system.text.stringbuilder.equals.aspx

StringBuilder.Equals () - это ...

true, если этот экземпляри sb имеют одинаковые значения string, Capacity и MaxCapacity;в противном случае false.

object.Equals () использует static Equals (), определенный для объекта , который проверяет только на равенство ссылок (если передан класс) или на равенство значений (если передано структура).

Итак, в итоге

string s1 = "t";
string s2 = 't'.ToString();        

Console.WriteLine(s1.Equals(s2)); // true because both reference equality (interned strings) and value equality (string overrides Equals())
Console.WriteLine(object.Equals(s1, s2)); // true because of reference equality (interned strings)

StringBuilder s1 = new StringBuilder();
StringBuilder s2 = new StringBuilder();

Console.WriteLine(s1.Equals(s2)); // true because StringBuilder.Equals() overloaded
Console.WriteLine(object.Equals(s1, s2)); // false because the two StringBuilder instances have different addresses (references not equal)
1 голос
/ 19 марта 2012

Строковый класс реализует Equals таким образом, что он сравнивает значения строк.

Большинство экземпляров объекта, если они не реализуют другой тип сравнения, проверяют, является ли объект ссылками одинаковыми.

Обратите внимание, что существует такжеслучай, когда две разные строковые константы, содержащие одно и то же значение, изначально назначаются одной и той же ссылкой на объект компилятором.

1 голос
/ 19 марта 2012

Универсальный метод Equals сравнивает ссылки двух объектов, чтобы определить, имеют ли они равенство reference для ссылочных типов, таких как StringBuilder.Для типов значений и string ведет себя как тип значения (является неизменным), он выполняет побитовое сравнение (определяет, является ли двоичное представление одинаковым).Эта функциональность, однако, перегружена в классе StringBuilder.

Согласно MSDN , метод равенства StringBuilder вернет true, если следующие критерии для обоих объектов StringBuilder равны:

  • String
  • Capacity
  • MaxCapacity

Таким образом, s1 и s2 во втором примере не справляются с равенством ссылок, но передают пользовательское равенство StringBuilder Equals на основе только что упомянутых критериев.

...