条件断点和监视窗口不会短路表达式求值。

3

[编辑 - 更改示例以避免混淆根问题]

在尝试弄清楚为什么我的条件断点在Visual Studio中会生成错误时,我偶然发现了一个我没有预料到的行为。

在观察窗口、立即窗口或断点条件中,Visual Studio似乎没有短路表达式求值。

例如,在此行后停止断点:

string obj = "hello";

在监视窗口中评估以下内容
obj is int && ((int)obj) == 1

应该给出结果

false

但是实际上却给出了

CS0030:无法将类型“string”转换为类型“int”

这会阻止我执行一些操作,例如检查对象的类型,然后将其强制转换为该类型并在我的条件断点中检查属性,这严重降低了它们的有用性。

其他人是否看到了这种行为,是否有人知道如何使条件断点/监视窗口短路?

我想到的一个不太理想的解决方法是在代码中将表达式包装在一个方法中,并从监视窗口中评估此方法。但是,这涉及更改代码和重新编译,而不能在调试时动态更改条件。


也许不相关,但如果您将第二个条件放入代码中的函数中,示例是否会失败?“除以常数零”让我感到怀疑。 - Rawling
2
@Rawling - 这只是一个例子,突出了问题。短路的缺乏也会在与除以零无关的其他代码中表现出来。例如,obj 是 string && ((string)obj) == "hello" 对于非字符串的 obj 将失败,并显示“无法转换”的错误信息。 - Rob Levine
如果零是一个变量,它就有效。这个可以运行:int y = 0; bool asdfg=false && (1 / y == 1); - Pikoh
使用您的第二个示例,我认为情况是相同的。在运行时,编译器知道obj不是一个字符串,因此它首先尝试在开始评估条件之前转换对象... - Pikoh
1
重点是:有一个问题,我无法使用应该很简单的条件断点来执行某些操作。从某种意义上说,我并不太关心它是否真正是短路问题或运行时问题;问题在于我无法在条件断点中检查类型,然后进行强制转换并检查其属性。 - Rob Levine
显示剩余6条评论
2个回答

3

实际上,这个语句在立即窗口或代码中都不起作用,因为编译器知道obj永远无法转换为int

如果您将obj定义为object,则会按预期工作。

object obj = "hello";
bool result = obj is int && ((int)obj) == 1;

上述代码将编译并作为断点条件工作。

正如leppie所提到的,您可以重新转换对象((int)(object) obj)来避免这种情况,但这应该始终是最后一招。


1

我曾经遇到过相同的问题,试图在值类型为object的通用属性设置器上中断。

(propertyName=="xxx") && (value is int) && ((int)value==5000)

用 ?: 操作符替换第二个 && 似乎可以解决问题。
(propertyName=="xxx") && ((value is int) ? ((int)value==5000) : false)

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