这非常危险,所以我想知道它为什么被允许。由于我经常需要在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
}
断点条件对话框:
包含断点的图像代码:
答案 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中,断点条件下的变量赋值表达式不再起作用。
将对表达式的值进行求值,但是将忽略诸如赋值之类的副作用。