Ci sono diverse cose in corso. In primo luogo, in questo esempio:
string s1 = "a";
string s2 = "a";
Console.WriteLine(s1 == s2);
Lei afferma che:
Entrambi sono differenti riferimento all'oggetto.
Questo non è vero a causa dello interno stringa.s1
e s2
sono riferimenti allo stesso oggetto. I C# specifica garantisce che - dalla sezione 2.4.4.5 della specifica C# 4:
Quando due o più stringhe letterali che sono equivalenti secondo l'operatore di uguaglianza stringa (§7.10.7) appaiono nello stesso programma, questi valori letterali stringa si riferiscono alla stessa istanza di stringa.
Quindi, in questo caso particolare, si sarebbe ancora ottenere "vero", anche se si è stampato object.ReferenceEquals(s1, s2)
, o se l'hai fatta usare un confronto vero identità di riferimento con ==
:
object s1 = "a";
object s2 = "a";
Console.WriteLine(s1 == s2); // Still prints True due to string literal interning
Tuttavia, anche se questi erano riferimenti a oggetti separati, ==
è sovraccarico per string
. Il sovraccarico è una decisione in fase di compilazione - l'implementazione da utilizzare dipende dai tipi di operandi in fase di compilazione. Così, per esempio:
string a = new string('x', 1);
string b = new string('x', 1);
Console.WriteLine(a == b); // Uses string's implementation, prints True
object c = a;
object d = b;
Console.WriteLine(c == d); // Reference identity comparison, prints False
Confronti che, con object.Equals(object)
che è un metodo virtuale. Come accade, lo String
sovraccarica questo metodo e, ma è importante che lo sostituisca. Quindi, se cambiamo il nostro codice a:
string a = new string('x', 1);
string b = new string('x', 1);
Console.WriteLine(a.Equals((object) b));
object c = a;
object d = b;
Console.WriteLine(c.Equals(d));
... poi entrambi le chiamate di metodo nel codice compilato sarà semplicemente a object.Equals(object)
, ma faranno ancora sia per la stampa vera causa del polimorfismo: la realizzazione in String
sarà usato.
Ecco cosa una chiamata al sovraccarico metodo sarebbe simile:
string a = new string('x', 1);
string b = new string('x', 1);
Console.WriteLine(a.Equals(b)); // Calls string.Equals(string)
Due domande: perché il cast di 'd' per' oggetto', dal momento che è già un oggetto? Inoltre, nella parte 'a Equals b', chiamerei sia l'override dell'oggetto, sia il sovraccarico di stringhe, quindi è più chiaro qual è la differenza. – doekman
@doekman: 1) Sì, non ho bisogno del cast in quel caso. 2) Non sei sicuro di cosa intendi. –
Intendo questo: vedi l'ultimo anwer. Non ho ricevuto direttamente la tua spiegazione su sovraccarico/override .... – doekman