2013-05-05 20 views
26

Mam pytanie dotyczące Object.Equals i Equals(object). Mój przykładowy kod znajduje się poniżej:C# Różnice między operatorem ==, StringBuilder.Equals, Object.Equals i Object.ReferenceEquals

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(); 
    } 
} 

Wyjście jest:

False 
True 
False 
False 

Ale o ile mi wiadomo Object.Equals(sb1, sb2) wewnętrznie wywołuje sb1.Equals(sb2) więc dlaczego nie dać dwa różne wyniki?

+0

Powinieneś wymyślić lepszy tytuł pytania. Prąd nic nie znaczy. Nie powtarzaj tagów w tytułach. –

+0

@ReferenceEquals: Porównujesz cztery metody porównywania. Zmodyfikowałem twój tytuł, aby lepiej odzwierciedlał twoje pytanie. –

+3

Dlaczego sprawdzasz równość na 2 stringbuilderach? To jest jak sprawdzanie strumienia lub autora tekstów pod kątem równości. – leppie

Odpowiedz

17

Brakuje kolejny test:

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

StringBuilder nie zastępują Equals(object), to przeciążenia go innym Equals(StringBuilder).

Object.Equals(object, object) dzwoni pod numer Equals(object), więc wynik jest fałszywy.

+0

Przeciążenie 'Równa 'bez nadpisania. WTF myśleli. Osobiście użyłbym referencyjnej równości, ale wybór ten jest po prostu mylący. – CodesInChaos

+1

Powinieneś wyjaśnić różnicę między [Object.Equals() '] (http://msdn.microsoft.com/en-us/library/bsc2ak47.aspx) i [' IEquatable '] (http: // msdn.microsoft.com/en-us/library/ms131187.aspx) –

+0

Ponieważ mamy dwie różne referencje (obiekty, instancje) i domyślne Równe (obiekt) powinniśmy najpierw zwrócić porównanie porównawcze. – Uzzy

4

Używasz 4 różne metody porównania skutkować różnymi wynikami:

  • Operator == wola domyślnie zrobić sprawdzenie czy odniesienia są równe. W tym przypadku masz dwa wystąpienia, więc mają dwa różne odniesienia. Zachowanie == można zastąpić dowolnym typem (np. string ma własną metodę porównania), ale w przypadku StringBuilder nie jest.
  • Metoda StringBuilder.Equals(StringBuilder) będzie porównywać z innym StringBuilder i porównuje niektóre wartości wewnętrzne. Te wartości są w twoim przypadku takie same. Dziwne jest to, że StringBuilder nie zastępuje metody, aby zastosować tę samą logikę.
  • Metoda object.Equals(object, object) spróbuje wywołać metodę .Equals(object) jednego z obiektów. W tym przypadku: StringBuilder.Equals(object), który, jak już powiedziałem, nie miał logiki do porównania wartości. W wyniku porównania odniesień obu wystąpień.
  • Object.ReferenceEquals po prostu porówna odniesienia.

Aby uzyskać więcej informacji, zobacz:

3

StringBuilder.equals nie porównuje obiekty lecz z MSDN:

„True jeśli ta instancja i SB mają równy ciąg, Pojemność, i MaxCapacity wartości; w przeciwnym razie false ".

Resztę czeków porównuje się z referencją.