为什么 Visual Studio 监视面板评估相等性的方式与我的程序不同?

Why does the Visual Studio Watch panel evaluate equality differently than my program?

提问人:AndrewR 提问时间:5/8/2023 最后编辑:gunr2171AndrewR 更新时间:5/8/2023 访问量:120

问:

在运行程序时,我正在使用 Visual Studio 的“监视”面板来调查变量。在下面的代码中,将 和 变量添加到“监视”面板中。不出所料,它们的计算结果均为 。test1test2true

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

bool test2 = (object)"123" == (object)"123";

但是,如第三行所示,如果我手动添加变量的表达式,它的计算结果为 .test2false

为什么同一行在“监视”窗口中产生不同的结果?这是这里的某种优化吗?在什么情况下,同一个字符串可以分配给不同的地址?

C# 可视化工作室 相等性

评论

0赞 knittl 5/8/2023
@AndrewR 监视窗口中的结果是什么?监视窗口中的结果是什么?监视窗口中的结果是什么?该值是最新的还是显示刷新图标/按钮?"123"=="123"a==b"123".Equals("123")
3赞 Hans Passant 5/8/2023
调试器具有内置 C# 编译器的感觉并不准确,它具有专用的表达式解析器。您的 C# 代码依赖于字符串文字的嵌入。因此,Object.operator==() 返回 true,则对象引用是相同的。这在调试器中不会发生。
0赞 Guru Stron 5/8/2023
也看看这个答案
0赞 AndrewR 5/8/2023
@knittl 都是真的。表达式不是方法调用,因此它始终是最新的

答:

6赞 Iridium 5/8/2023 #1

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

由于上述原因,代码中的所有用法在运行时都是相同的字符串实例,这就是为什么 和 are ,因为 you 正在执行引用相等,并且在这两种情况下两端都是相同的字符串实例。"123"test1test2true==

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

评论

0赞 AndrewR 5/8/2023
因此,基本上答案是编译器在编译期间检查常量是否相等,但在执行期间不检查,这包括“监视”窗口
2赞 Iridium 5/8/2023
@AndrewR - 它的内容略多于此,因为它依赖于字符串“实习”(我已经更新了我的答案来澄清这一点)。您可以使用 来显示这种情况的发生,例如:在监视窗口中,两者甚至甚至。string.Intern()(object)string.Intern("123") == (object)a(object)string.Intern("123") == (object)string.Intern("123")true
0赞 AndrewR 5/8/2023
知道了,谢谢。在今天之前,我认为 .NET 总是在创建字符串时对其进行实习。