为什么 Visual Studio Watch 面板对相等性的评估与我的程序不同?

And*_*ewR 4 c# equality visual-studio

我在运行程序时使用 Visual Studio 的监视面板来调查变量。在以下代码中,test1test2变量都添加到“监视”面板中。正如预期的那样,它们的评估结果都是true

object a = "123";
object b = "123";
bool test1 = a == b;

bool test2 = (object)"123" == (object)"123";
Run Code Online (Sandbox Code Playgroud)

但是,如第三行所示,如果我手动添加test2变量的表达式,则其计算结果为false

为什么同一行在 Watch 窗口中产生不同的结果?这是这里工作的某种优化吗?什么情况下可以将同一个字符串分配到不同的地址?

Iri*_*ium 6

这里发生了一些事情,首先是当您在 C# 代码中使用字符串文字时,这些文字必须包含在已编译的程序集中,因此为了避免程序集膨胀,编译器仅输出每个唯一字符串一次,并且它们在运行时自动“实习”(请参阅​​: https: //learn.microsoft.com/en-us/dotnet/api/system.string.intern)。因此,给定字符串文字的所有使用都将是同一字符串实例。

\n

由于上述原因,"123"代码中的所有使用在运行时都是相同的字符串实例,这就是为什么test1test2都是true,因为您==正在执行引用相等,并且在两种情况下双方都是相同的字符串实例。

\n

但是,当您使用监视窗口时,调试器会为表达式中的每个字符串文字创建新的字符串实例,因此它们不是同一实例,因此将它们与object\xe2\x80\x99s进行比较==会返回false

\n

  • @AndrewR - 比这稍微多一点,因为它依赖于字符串“interning”(我已经更新了我的答案以澄清这一点)。您可以通过使用 `string.Intern()` 来显示这种情况的发生,例如: `(object)string.Intern("123") == (object)a` 甚至 `(object)string.Intern("123")即使在监视窗口中, ) == (object)string.Intern("123")` 也将为 `true`。 (2认同)