为什么字符串不比较引用?

10

我知道这是一个特殊情况,但为什么在字符串之间使用==时,它返回它们的值是否相等而不是引用是否相等。这与重载运算符有关吗?

5个回答

21

== 操作符在 String 中被重载,用于执行值相等性而不是引用相等性。这个想法是使字符串更加友好,避免使用引用相等性来比较它们时出现的错误(在 Java 中并不罕见,尤其是对于初学者来说)。

老实说,到目前为止我从未需要按引用比较字符串。如果你需要这样做,可以使用object.ReferenceEquals()


6
没错。"更加友好于程序员"。在C#中我们不使用指针。我们想要能够这样编写代码,例如if (name == "jim")而不是if (name.ValueEquals("jim")) - Jim Mischel
5
@Jim: 老实说,我很惊讶这个通用语言特性还没有被广泛采用:你使用 == 运算符时总是进行值相等性比较,而需要一个特殊的运算符/方法来进行引用相等性比较,而不是反过来。通常情况下,我更经常比较值而不是引用(除非在处理引用时)。 - Joey

7

由于字符串是不可变的,运行时可能选择将具有相同内容的任何两个字符串放在同一个引用中。因此,对字符串进行引用比较实际上没有任何意义。


1
不,这是错误的。你可能在想C#而不是Java。虽然你描述的机制(字符串内部化)确实存在于.NET中,但它并不真正涉及到这个问题。字符串的不可变性并不会先验地回答为什么operator ==执行值比较的问题。 - Konrad Rudolph
@Konrad Rudolph:我仍然认为在这种情况下进行引用比较是没有意义的。虽然这可能不是选择该方式的唯一原因,但当您预期两个字符串在初始化时是分别引用不同的对象但实际上它们是相同的引用时,由于发生了interning,这确实会使您感到困扰。 - TToni
嗯,例如运行时的事情是错误的。运行时将对字符串字面量执行此操作。但更重要的是,你的“所以”真的是一个不合适的推论。你暗示的答案的第一部分和第二部分之间的因果关系根本不存在。此外,责任在于使用官方参考证明这一点,而不是我去反驳它。 - Konrad Rudolph
@Konrad Rudolph:同时编辑评论会导致尴尬的“对话” :-) - TToni
我实际上想要比较字符串的引用,但不知道在我的情况下是否适用。幸运的是,Object.ReferenceEquals方法在msdn文档中有关于字符串的部分:https://msdn.microsoft.com/zh-cn/library/system.object.referenceequals.aspx。在我的情况下,字符串是从文件读取的,所以应该可以比较引用。(我的情况是:我合并(有序)字符串列表,其中字符串可能具有相同的内容,我希望稍后能够将其拆分。顺序并不是至关重要的,但肯定很好) - Emile Vrijdags
显示剩余2条评论

2

是的。从.NET Reflector中,这是String类的等号运算符重载:

public static bool operator ==(string a, string b)
{
    return Equals(a, b);
}

2

等号运算符 (==!=) 的作用是比较字符串对象的值,而不是引用。

我在任何情况下都没有必要比较引用,但如果你想这样做,可以使用以下方法:

object.ReferenceEquals().

2

在字符串中,==是通过值比较的(value)

“虽然字符串是引用类型,但等式运算符(==和!=)被定义为比较字符串对象的值,而不是引用(7.9.7字符串等式运算符)。这使得测试字符串相等更加直观。”

简而言之,在字符串上,==是通过值比较字符串,而不是通过引用比较,因为C#规范规定应该这样做。


答案中的链接无效。有效链接:https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/equality-operators#string-equality - Lafi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接