有几件事情发生了。首先,在这个例子中:
string s1 = "a";
string s2 = "a";
Console.WriteLine(s1 == s2);
你声称:
Both are different object reference.
这是不正确的由于字符串实习。 s1和s2是对同一个对象的引用。 C#规范保证 – 从C#4规范的2.4.4.5节:
When two or more string literals that are equivalent according to the string equality operator (§7.10.7) appear in the same program, these string literals refer to the same string instance.
所以在这种特殊情况下,即使你打印了object.ReferenceEquals(s1,s2),或者如果你使用了与
object s1 = "a";
object s2 = "a";
Console.WriteLine(s1 == s2); // Still prints True due to string literal interning
然而,即使这些引用是单独的对象,==被重载为字符串。重载是一个编译时的决定 – 使用的实现取决于操作数的编译时类型。所以例如:
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
与object.Equals(object)作为虚拟方法进行比较。发生这种情况,String也会重载此方法,但重要的是它会覆盖它。所以如果我们将代码改为:
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));
…然后,编译代码中的两个方法调用将简单地是object.Equals(object),但是由于多态性,它们仍然会打印True:String中的实现将被使用。
以下是对重载方法的调用如下所示:
string a = new string('x', 1);
string b = new string('x', 1);
Console.WriteLine(a.Equals(b)); // Calls string.Equals(string)