为什么调试器的断点条件允许赋值语句为bool-condition?

时间:2015-02-06 12:57:04

标签: c# vb.net visual-studio-2010 debugging breakpoints

这非常危险,所以我想知道它为什么被允许。由于我经常需要在VB.NET和C#之间切换,我有时会添加断点条件,如下所示:

foo = "bah"

如果string变量foo"bah,我想停止,因此正确的方法是使用foo == "bah"代替foo = "bah"

但它"工作"。在编译或运行时,您不会收到任何警告或错误。但实际上这个修改了变量foo,即使它具有不同的值,它也始终为"bah"。由于这种情况无声地发生(断点永远不会被击中),这是非常危险的。

为什么允许?我的推理错误在哪里(除了混淆C#和VB.NET语法)?在C#中(与VB.NET相反),assignment statement返回已分配的值,因此不是bool,而是string。但是,如果您选中" Is True" 框,则断点条件必须为bool

这是一个小样本"程序"和我(德国)IDE的截图:

static void Main()
{
    string foo = "foo";
    // breakpoint with assignment(foo = "bah") instead of comparison(foo == "bah"):
    Console.WriteLine(foo);  // bah, variable is changed from the breakpoint window
}

断点条件对话框:

enter image description here

包含断点的图像代码:

enter image description here

3 个答案:

答案 0 :(得分:7)

这是C#语法的自动结果,在大括号语言组中很常见。赋值也是一个表达式,其结果是右侧操作数的值。调试器既不会反对具有副作用的表达式,也不会简单地抑制它们。可以归咎于没有检查表达式是否有 bool 结果,但是调试器没有完整的C#语言解析器。由于Roslyn项目,这可能在VS2015中得到修复。 [注:见底部的附录]。

这也是大括号语言需要一个单独的运算符进行相等的核心原因,== vs =。每个C程序员至少应该犯一次价值十亿美元的错误,这本身就至少犯了一次错误。

VB.NET不同,赋值是一个语句,=标记对赋值和比较都有效。您可以从调试器中获知,它选择了相等运算符而不修改变量。

请记住,这实际上很有用。它允许您临时解决错误,强制变量值并允许您继续调试并专注于另一个问题。或者创建一个测试条件。这非常有用。在之前的一生中,我编写了一个编译器和调试器并实现了#34;跟踪点"。偶然发现了相同的场景并将其留在原地。它运行在严重依赖状态机的主机上,覆盖状态变量,而调试非常有用。事故,不,不那么有用:)


关于其他SO用户观察的内容的注释,它取决于您使用的调试引擎。 VS2013中的相关选项是工具+选项,调试,常规,"使用托管兼容模式"复选框。 VS2012中存在相同的选项,它的名称略有不同(不记得)。勾选后,您将获得一个较旧的调试引擎,该引擎仍然与C ++ / CLI兼容。与VS2010中使用的相同。

这是VS2013的一种解决方法,取消选项以让调试器检查表达式是否产生bool结果。您可以使用新的调试引擎获得更多好处,例如查看方法返回值和编辑+继续支持64位进程。

答案 1 :(得分:1)

我可以不同意这种行为的错误性质。在我的生活中用于调试目的的几个例子如果有用:
1.其他线程修改代码中的内容 2. db中的其他服务更新值 因此,我认为对于同步的情况,它可能是有用的功能,但我同意它可能会导致问题

答案 2 :(得分:1)

在Visual Studio 2019中,断点条件下的变量赋值表达式不再起作用。

将对表达式的值进行求值,但是将忽略诸如赋值之类的副作用。

https://developercommunity.visualstudio.com/content/problem/715716/variables-cannot-be-assigned-in-breakpoint-conditi.html