2012-03-19 3 views
8
 string s1 = "t"; 
     string s2 = 't'.ToString();   

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

Qui restituisce lo stesso risultato. Ora, quando sto usando StringBuilder, non restituisce lo stesso valore. Qual è la ragione sottostante?Perché object.Equals e instanceobject.Equals non sono uguali

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

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

Edit1: La mia domanda di cui sopra risponde sotto. Durante questa discussione, tuttavia, scopriamo che StringBuilder non ha alcun metodo di sovrascrittura Equals nella sua implementazione. Quindi, quando chiamiamo StringBuilder.Equals, in realtà va a Object.Equals. Quindi, se qualcuno chiama StringBuilder.Equals e S1.Equals (S2) il risultato sarà diverso.

+1

Buona cattura! In conclusione, 'StringBuilder' sembra dimenticare di sovrascrivere' Equals (oggetto) '. Sembra controintuitivo avere 'Equals (StringBuilder)' con un comportamento diverso da 'Equals (oggetto)'. – leppie

risposta

7

String.Equals() viene sovrascritto in C# tale che stringhe identiche sono infatti Equal() quando viene usato il Equal() sostituzione definita su string.

Se si confrontano string literals (non è il caso nel tuo esempio), vale la pena notare che identici stringhe letterali sono interned ... cioè, stringhe identiche vivono allo stesso indirizzo in modo sarà anche uguale per riferimento (ad esempio, oggetto .Equals() o s1.ReferenceEquals (s2)) nonché per valore.

StringBuilder fornisce un sovraccarico di Equals() che prende StringBuilder come parametro (cioè s1.Equals(s2) chiamerà che il sovraccarico invece di chiamare object.Equals(object obj)).

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

StringBuilder.Equals() è ...

vero se questa istanza e sb hanno pari stringa, Capacità, e valori MAXCAPACITY; altrimenti, falso.

Object.equalsQ() utilizza il static Equals() defined on object, che controlla solo per la parità di riferimento (se sottoposte a una classe) o per value equality (se superato uno struct).

Quindi, in sintesi

implementa classe
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) 
+5

Tecnicamente StringBuilder sovrascrive solo il metodo Equals senza sovrascrivere l'oggetto virtuale. Equals (oggetto). Questo è il motivo per cui due metodi si comportano diversamente. Mi chiedo se si sono dimenticati di farlo in NET1.0 e non volevano introdurre un cambiamento di rottura? – alexm

+0

@alexm: buona cattura. Non l'avevo notato prima. Aggiornato la mia risposta. –

+0

Thaks Eric per la bella spiegazione. Se faccio un piccolo riassunto: object.Equals controllerà che il riferimento o il valore dipendano dal tipo di oggetto di input. Mentre String e StringBuilder hanno il proprio metodo Equal sovraccarico/sovrascritto che funzionerà secondo la loro implementazione. Per favore correggimi se sbaglio. –

1

Il generic Equals method confronta i riferimenti dei due oggetti per vedere se hanno riferimento uguaglianza per i tipi di riferimento come ad esempio StringBuilder. Per valori tipi e string si comporta come un tipo di valore (è immutabile), si esegue un confronto bit per bit (determina se la rappresentazione binaria è lo stesso). Questa funzionalità, tuttavia, è sovraccaricata nella classe StringBuilder.

Secondo MSDN, il metodo di parità di StringBuilder restituisce true se i seguenti criteri per entrambi gli oggetti StringBuilder sono uguali:

  • String
  • Capacità
  • MaxCapacity

Così, s1 e s2 nel secondo esempio sicuro uguaglianza riferimento, ma passare l'abitudine StringBuilder uguale parità sulla base dei criteri ricordati.

+0

La stringa non è un tipo di valore. (È un tipo di riferimento con semantica del valore.) Http://stackoverflow.com/questions/1069155/is-string-a-value-type-or-a-reference-type –

+0

@BradleyGrainger, sapevo che non è tecnicamente un tipo di valore, ma in questo caso agisce allo stesso modo. Aggiornerò la mia risposta per chiarire però. Grazie. – Matt

1

la stringa uguali in modo tale che confronta i valori delle stringhe.

La maggior parte delle istanze di oggetti, a meno che non implementino un diverso tipo di confronto, verifica se gli oggetti riferimenti sono uguali o meno allo.

Si noti che esiste anche un caso in cui due diverse costanti di stringa che contengono lo stesso identico valore vengono inizialmente assegnate allo stesso riferimento oggetto dal compilatore.