VS2008调试器是否保持超出范围对象?

时间:2010-11-19 19:11:15

标签: c# .net visual-studio debugging

给出这段代码:

// Get first key //
int? keyEDISecurity = this.WorkQueue.GetNextWorkItem();

// Done? //
while (keyEDISecurity != null)
{
    try
    {

        ...

        // Write changes //
        List<ISNLEditableObject> changedRows = this.WorkQueue.GetChangedRows((int)keyEDISecurity);
        this.Writer.Write(changedRows, WriteFlags.Transactional);

        ...
    }
    catch (Exception ex)
    {
        // Exception handling/logging code
    }
    finally
    {
        // Remove all data for the KeyEDISecurity from work queue cache //
        this.WorkQueue.RemoveData((int)keyEDISecurity);
    }

    // Get next work item //
    keyEDISecurity = this.WorkQueue.GetNextWorkItem();
}

在具有声明List changedRows的行之前,changedRows应为null。然后它会超出范围,因为你得到了下一个工作项。然后你回来,在同一行之前,如果你访问changedRows,它应该再次为null,因为它没有被声明。

如果您中断并编辑,那么,正如您所期望的那样,您无法访问changedRows,因为它已超出范围,尚未声明。如果您评估它(通过鼠标悬停或使用立即窗口),您可以访问上一次循环迭代中的changedRows。 WTH?

有人见过这个吗?它不会影响程序,因为它似乎在代码中正确运行,但调试器问题导致浪费时间,因为它没有按预期运行。我想知道这是否是预期的行为,所以我可以在将来知道,而不是浪费时间。

1 个答案:

答案 0 :(得分:6)

这是特定于实现的优化。

执行函数时,通常会立即在堆栈上创建所有变量。即使语言不允许访问它们,它们也在那里。这就是为什么changedRows在声明之前就是null的原因。

当变量超出范围时,语言不允许再次使用它,但它仍然存在于堆栈中。它的值不需要更改为null,因为它不会在任何地方使用。这会浪费处理器时间。这就是保留changedRows的值的原因,即使根据语言规则,它必须被销毁(当它超出范围时)并再次创建(当它被声明时)。

调试器不遵守所有语言规则。事实上,甚至可能会被一些结构搞糊涂。当您尝试获取变量的值时,调试器不会检查它是否在范围内等。