0

参考this question为什么下面的代码总是返回true?[c#语言]

String a= "hello";
String b= "hello";
if(a==b)
Console.WriteLine("Is it really reference type?");

只是想解释一下为什么它们在这里表现为值类型而不是引用类型。有没有关于这个的任何 MSDN 文档,或者我应该记住这个异常,或者这完全合乎逻辑但我不明白吗?

详细解释表示赞赏。

4

3 回答 3

12

任何类都可以覆盖==运算符以提供自定义比较。文档

这就是String类的作用——它只是为比较提供了不同的含义——它检查字符串值而不是对象引用。

如果您真的想检查实例是否指向相同的引用,请使用object.ReferenceEquals(a, b)

就字符串而言,在这种情况下它们实际上是相同的引用 - 编译器将检测到字符串值完全相同并将它们存储在内存中一次。这里有一些关于String.Intern

于 2013-05-16T10:41:30.543 回答
2

在 .NET 中,字符串的处理方式略有不同。尽管它们是引用类型,但它们似乎充当值类型。

其基本原因是字符串是不可变且唯一的。这意味着当您定义字符串 a 时,值“hello”将保存在堆中。

当您定义字符串 b 并为其分配值“hello”时,它将知道堆上已经有一个具有该值的字符串,然后创建指向同一字符串的指针。它可以安全地执行此操作,因为字符串是不可变的,因此 CLR 知道该字符串永远不会被修改。任何修改字符串的操作,只会导致在堆上分配一个新字符串。

于 2013-05-16T10:44:36.877 回答
2

字符串运算符被重载以检查值相等而==不是引用相等,即使String是引用类型。Microsoft 建议对具有值语义的引用类型执行此操作:

但是,如果您正在实现旨在具有值语义的引用类型,例如复数类型,则必须覆盖相等运算符。

有关详细信息,请参阅Object.Equals 方法(对象)

于 2013-05-16T10:45:23.343 回答