在调试器中唯一标识引用类型

53

我来自C++背景,如果这是一种非C#思考方式,请见谅,但我只需要知道。

在C++中,如果我有两个指针,我想知道它们是否指向同一件事物,我可以查看内存/监视窗口并查看它们的值-看它们是否指向相同的内存空间。

在C#中,我没有找到类似的东西。 一个具有完全相同值的引用类型实际上可能是完全相同的对象,也可能是完全不同的东西。

是否有一种方法让我在C#中查看这种信息?也许有某种等效于&运算符的监视窗口或类似的东西吗?

4个回答

87
你需要寻找对象ID。在调试器中,对于任何引用类型,你可以右键单击并选择"Make Object ID"。每当该实例在调试器中显示时,这将在值列中添加一个#后缀。你还可以在监视窗口中添加#1、#2等等来随时再次查看它们。
步骤0 - 运行此代码。
static void Main(string[] args)
{
    var x = "a string";
    var y = x;
    System.Diagnostics.Debugger.Break();
}

步骤1-右键单击并选择“创建对象ID”

alt text

步骤2-实例现在显示为带有1#后缀的形式。注意:在此步骤中,我没有做任何特殊的事情。点击“创建对象ID”后,由于它们引用同一实例,两个行立即更新以显示1#后缀。

alt text

步骤3-随时通过将1#添加到监视窗口来查看它们

alt text


9
太酷了,我从未听说过对象 ID。在 Visual Studio 中有很多这样的“隐藏”的小功能。 - Alastair Pitts
1
太棒了。解释得非常好,视觉效果也很性感。+1并且是正确的答案。 :) - Eddie Parker
3
在 VS 2015 中,语法似乎是 $1、$2 等。 - Justin Caldicott
当你观察的对象不存在时会发生什么?我正在调试与EF DbContext相关的一些内容,似乎这些对象即使(我希望)已经被处理掉了,它们仍然停留在本地窗口中。 - Bartosz
尝试过了,"从一个断点到另一个断点"不起作用。就好像我在单个方法中有问题记住一个被引用的对象一样...我必须处理代码中的某种“全局”对象,没有人能够解释给我(没有文档,开发人员已经“不存在”)。这些全局对象有时会被重新创建,我认为在某些地方这些重新创建没有被完全识别,并且某些变量仍然引用旧对象。在C ++中使用指针很容易找到(可能在VS中不行,不知道),或者在Android Studio中使用引用ID也可以找到。 - The incredible Jan
显示剩余2条评论

6
在C#项目中,如果您在变量窗口之一中右键单击变量名称并选择“创建对象 ID”,Visual Studio将为该实例分配一个唯一的 ID 并在值列中显示它。这些 ID 看起来像 {1#}、{2#} 等等。如果两个对象具有相同的 ID,则它们是引用相同的。
在代码或立即窗口中,您还可以使用 Object.ReferenceEquals() 来检查两个对象是否相同。
我认为没有一种好方法可以在调试器中获取对象的实际内存地址。我猜这是有意设计的,因为在托管应用程序中垃圾回收期间,对象在内存中的位置可能会发生变化。当然,您可以声明一个不安全块,固定对象,并使用所有常规的 C/C++ 运算符获取指向它的指针。然后,您就可以在调试器中看到指针的值。但我不建议这成为一个好习惯——固定对象往往会干扰垃圾收集器维护有序堆的能力,这反过来可能导致更差的性能和内存消耗。

1
要在观察窗口中查看变量的内存地址,请在变量名前加上“&”符号。例如:&varName。 - boylec1986

1

我该如何判断一个引用是否指向之前的同一对象? - The incredible Jan

0

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