假设我的班级有一个名为 count 的私有整数变量。
我已经在我的代码中遇到了断点。现在,在我按下继续之前,我想让调试器在 count 获得分配给它的新值时停止。
除了将 count 提升到字段并在字段的 set 方法上设置断点之外,还有其他方法可以做到这一点吗?
假设我的班级有一个名为 count 的私有整数变量。
我已经在我的代码中遇到了断点。现在,在我按下继续之前,我想让调试器在 count 获得分配给它的新值时停止。
除了将 count 提升到字段并在字段的 set 方法上设置断点之外,还有其他方法可以做到这一点吗?
您正在寻找的内容在托管代码中是不可能的。在 C++ 中,这称为数据断点。它允许您在正在运行的程序更改内存块时中断。但这仅在纯本机 C++ 代码中可用。
为什么没有实现它的简短版本是它在托管代码中要困难得多。本机代码很好且可预测。您创建内存并且它不会移动,除非您创建一个新对象(或显式复制内存)。
托管代码要复杂得多,因为它是一种垃圾收集语言。CLR 通常在内存中移动对象。因此,仅仅看一点记忆是不够的。它需要GC交互。
这只是实施托管断点的问题之一。
我假设您正在尝试这样做,因为您想查看价值变化的来源。您已经说明了我一直这样做的方式:创建一个属性,然后在 set 访问器上中断(除非您必须始终使用该 set 访问器才能使其工作)。
基本上,我会说,由于私有字段只是存储,因此您不能对其进行破坏,因为私有字段不是可破坏的指令。
我能想到的唯一方法是右键单击变量,然后选择“查找所有引用”。找到所有引用后,您可以在代码中为变量赋值的每个点创建一个新断点。这可能会很好地工作,除非您通过引用另一个函数来传递变量并更改其中的值。在这种情况下,您需要某种方式来观察内存中的特定点,以了解它何时发生变化。我不确定VS中是否存在这样的工具。
就像 ChrisW 评论的那样。您可以设置“数据断点”,但仅适用于本机(非托管)代码。当垃圾收集器运行时,垃圾收集器将移动分配的内存块。因此,托管代码无法设置数据断点。
否则,没有。您必须封装对您想要“修改时中断”的项目的访问。由于它已经是私有成员,我建议遵循 Kibbee 的建议,在使用的任何地方设置断点。
除了将 count 提升到字段并在字段的 set 方法上设置断点之外,还有其他方法可以做到这一点吗?
使其成为不同类的属性,创建该类的实例,并在该属性上设置断点。
代替 ...
test()
{
int i = 3;
...etc...
i = 4;
}
... 有 ...
class Int
{
int m;
internal Int(int i) { m = i; }
internal val { set { m = value; } get { return m; } }
}
test()
{
Int i = new Int(3);
...etc...
i.val = 4;
}
问题是,使用 C#,所有内容的实际内存位置都在不断移动:因此调试器不能轻易使用 CPU 的“内存访问中断”调试寄存器,而调试器更容易实现代码位置断点。