【问题标题】:Conditional breakpoints and watch window do not short-circuit expression evaluation条件断点和监视窗口不会使表达式评估短路
【发布时间】:2016-09-20 05:05:30
【问题描述】:

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

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

在监视窗口、立即窗口或作为断点条件的情况下,Visual Studio 不会出现短路表达式求值。

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

string obj = "hello";

并在监视窗口中评估以下内容

obj is int && ((int)obj) == 1

应该给出结果

false

而是给了

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

这使我无法执行诸如检查对象的类型,然后强制转换为该类型并检查条件断点中的属性之类的事情,这严重降低了它们的实用性。

其他人是否看到这种行为,是否有人知道如何制作条件断点/观察窗口短路?

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

【问题讨论】:

  • 可能无关紧要,但是如果您将第二个条件放在代码中的函数中,该示例是否会失败? “除以 常数 零”让我很怀疑。
  • @Rawling - 这只是一个突出问题的例子。短路的缺乏也体现在与除以零无关的其他代码中。例如 obj is string && ((string)obj) == "hello" 对于非字符串将失败,并出现“无法转换”错误。
  • 如果零在变量中,它会起作用。这有效:int y = 0; bool asdfg=false && (1 / y == 1);
  • 在即时窗口中,false && ((System.Func<bool>)(() => { throw new System.Exception(); }))() 评估为假而不是抛出。 (而true && ... 抛出。)
  • 重点是:有一个问题,我不能用一个应该很简单的条件断点来做一些事情。从某种意义上说,我不太在乎它是真正的短路问题,还是运行时问题;问题是我无法检查类型,然后强制转换并检查其属性,所有这些都在条件断点内。

标签: c# .net visual-studio visual-studio-2015


【解决方案1】:

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

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

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

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

正如 leppie 所提到的,您可以重新投射您的对象 ((int)(object) obj) 以避免这种情况,但这应该始终是最后的措施。

【讨论】:

    【解决方案2】:

    我在尝试破坏值类型为 object 的通用属性设置器时遇到了同样的问题

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

    用 ?: 运算符替换第二个 && 似乎可以解决问题

    (propertyName=="xxx") && ((value is int) ? ((int)value==5000) : false)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-01-23
      • 2015-02-22
      • 2017-10-06
      • 1970-01-01
      • 1970-01-01
      • 2019-03-06
      • 2019-03-16
      • 1970-01-01
      相关资源
      最近更新 更多