我们知道 String 是一种引用类型并且是不可变的,所以这样做是合理的。它表示存储在 Stack 中的字符串的地址及其在 Heap 部分内存中的内容存储。另一方面,我们知道“==”操作只是比较堆栈值。因此,例如,我们有以下代码,如我们在理论上所期望的那样比较两个对象。
在 Microsoft Docs 中,我们有:
默认情况下,如果两个非记录引用类型操作数引用同一个对象,则它们是相等的:
public static void Main()
{
var a = new MyClass(1);
var b = new MyClass(1);
var c = a;
Console.WriteLine(a == b); // output: False
Console.WriteLine(a == c); // output: True
}
Run Code Online (Sandbox Code Playgroud)
但我的问题是为什么在引用类型为“==”的字符串中,操作的行为类似于值类型!我只是对技术原因以及 Dotnet 如何为之而感到好奇,而不仅仅是概念(如这里)
string t1 = "test";
string t2 = "test";
bool result = t1 == t2; // output: True
Run Code Online (Sandbox Code Playgroud)
如评论中所述,stringtype 仅实现自定义相等比较运算符。任何类都可以这样做并使==(和其他相等运算符)表现得“像值类型”。例如,这就是对新的“记录”类型所做的,这些类型是引用类型但行为“类似”值类型。
然而,还有一件事。在您的示例代码中:
string t1 = "test";
string t2 = "test";
bool result = t1 == t2; // output: True
Run Code Online (Sandbox Code Playgroud)
即使您检查两个字符串是否实际引用同一个对象,它仍然会返回 true:
bool result = Object.ReferenceEquals(t1, t2); // output: True
Run Code Online (Sandbox Code Playgroud)
那是因为它们实际上是指同一个对象,因为字符串实习。程序中有一个全局字符串池,可以在其中放置一个字符串,或者如果字符串已经存在 - 获取对同一字符串的引用(通过String.Intern调用)。程序中自动声明的所有字符串文字都放在那里。这意味着双方t1并t2指向同一个字符串对象在池中实习生。
如果您执行以下操作:
string t1 = "test";
string t2 = new StringBuilder().Append("test").ToString();
bool result = Object.ReferenceEquals(t1, t2);
Run Code Online (Sandbox Code Playgroud)
然后t2不再自动实习并且比较将返回假(但当然,比较==仍然会返回真)。
| 归档时间: |
|
| 查看次数: |
77 次 |
| 最近记录: |