ReferenceTypes和字符串的相等和比较:
引用类型的工作方式如下:
System.Object a = new System.Object();
System.Object b = new System.Object();
a == b; //returns true
a.Equals(b); //returns false
b = a;
a == b; //returns true
a.Equals(b); //returns true
由于字符串是引用类型,它们应该做同样的事情,不是吗?但他们没有!
C# 文档定义字符串相等,如下所示:
尽管字符串是一种引用类型,但相等运算符(== 和 !=)被定义为比较字符串对象的值,而不是引用(7.9.7 字符串相等运算符)。这使得对字符串相等性的测试更加直观。
https://msdn.microsoft.com/en-us/library/362314fe%28v=vs.71%29.aspx
https://msdn.microsoft.com/en-us/library/aa664728%28v=vs.71 %29.aspx
这对您的测试代码有影响。
if (str == str2)
{
Console.WriteLine("Something");
} // This is comparision of value even though string is a referenceType
if (str.Equals(str2))
{
Console.WriteLine("Something");
} // This is comparison by value too, because Equals is overrided in String class.
请记住,您作为程序员(或您棘手的同事)可以覆盖 .Equals(),改变它的行为,您在上面看到的是应该发生的事情。它不一定符合您的代码库现实,如有疑问,请通过标记 .Equals() 并按 F12 查看定义。
x.Equals 的附录
object.Equals() 的行为应该遵循以下规则:
每当您有疑问时,您都可以调用 x.ReferenceEquals,它的定义如下:
与 Object.Equals(Object) 方法和相等运算符不同,Object.ReferenceEquals(Object) 方法不能被覆盖。因此,如果您想测试两个对象引用的相等性并且您不确定 Equals 方法的实现,您可以调用该方法。
https://msdn.microsoft.com/de-de/library/system.object.referenceequals%28v=vs.110%29.aspx
因此:
System.Object a = new System.Object();
System.Object b = a;
System.Object.ReferenceEquals(a, b); //returns true
在您的示例中,编译器会在优化中合并您的字符串,因此:
string str = "hello";
string str2 = "hello";
string.ReferenceEquals(str, str2); // Comparison of reference (True)
在您的示例中,此行为仅与编译器优化有关,如果我们随机化代码,它将返回 false:
string str = "hello";
string str2 = "hello";
if(throwCoin)
{
str2 = "bye";
}
string.ReferenceEquals(str, str2); // Comparison of reference (False)