C# 关于对象标识、对象相等和字符串类异常的问题

C# 关于对象标识、对象相等和字符串类异常的问题,c#,java,identity,equality,C#,Java,Identity,Equality,这是一个Java和C的问题。 我们都知道,Object Identity(=)测试两个对象是否引用相同的位置,Obejct Equality(Equals方法)测试两个不同(不相同)的对象是否具有相同的值。但是在字符串的情况下,Object Identity和Object Equality是相同的。 例如,if语句中的两个布尔表达式返回true string a="123"; string b="123"; if(a==b) if(a.Equals(b)) 为什么会这样?? 这个设计决策背后的

这是一个Java和C的问题。 我们都知道,Object Identity(=)测试两个对象是否引用相同的位置,Obejct Equality(Equals方法)测试两个不同(不相同)的对象是否具有相同的值。但是在字符串的情况下,Object Identity和Object Equality是相同的。 例如,if语句中的两个布尔表达式返回true

string a="123";
string b="123";
if(a==b)
if(a.Equals(b))
为什么会这样??
这个设计决策背后的理性是什么?

Java和C都使用了一种称为。因为字符串在这些语言中是不可变的,所以它们可以将经常使用的字符串(包括硬编码的字符串文本,如您的示例中所示)汇集在一起,并在内存中使用对该字符串的多个引用来节省空间。

实际上,至少在Java中,字符串上有一种缓存机制。一个陷阱是两个相等的字符串有时会返回true,但在应用identity运算符时并不总是返回true。以下代码打印为false:

String a="123";
String b="12";
b=b+"3";
System.out.println(a==b);

如果确实希望确保两个字符串a和b的
a.equals(b)=true
(a==b)==false
计算结果为false,则可以使用完全低估的(^^^)字符串构造函数:

String a = new String("abc");
String b = new String("abc");
if (a.equals(b)) {
   doTheyAreEqual();
   if (a != b) {
     doButNotTheSame();
   }
}

据我所知,在.net中,字符串的
==
运算符重载为使用
Equals()
而不是对象标识。有关详细信息,请参见此说明:

如果您需要知道它是否真的是同一个对象,请使用以下命令:

Object.ReferenceEquals(string1, string2)

我建议您阅读Object.equals()和String.equals()的代码,您会发现这是不正确的。在C#中,“==”不被视为身份测试。它通常实现为执行类的EQUALS方法所做的任何操作。“ReferenceEquals(a,b)”是.Net的身份测试。在C#中,这两个测试的结果都是“true”。ReferenceEquals(a,b)将计算为“false”。