1

我不知道以下代码是否真的相关,但为了充分披露,这里是我试图从即时窗口调用的代码:

abstract class Test
{
    public int x;

    public Test()
    {
        x = 5; 
    }
}

class TestImp : Test
{
    public int GetX()
    {
        return this.x;
    }
}

这只是一个测试,看看默认的基本构造函数是否被自动调用,或者我是否必须专门调用它,因为我不记得了。

好的,直奔问题。我在即时窗口中输入了这个来查看结果:

new Mercury_Reports.TestImp().GetX();

而不是评估表达式,它只是启动了我的应用程序。我关闭了应用程序并再次尝试了两次并得到了相同的结果。下一次,我在我的 Program.cs 文件中放置了一个断点。然后,它没有像过去 3 次那样启动应用程序然后到达断点,而是决定实际上只评估我的表达式。

我以前在 Visual Studio IDE 中看到过一些奇怪的事情,但我认为这是最奇怪的事情之一。有人知道那里发生了什么吗?:)

4

1 回答 1

3

在不调试时在即时窗口中评估表达式时,会发生以下过​​程

  • 将您的项目/应用程序二进制文件加载到托管进程中
  • 以静默方式将调试器附加到托管进程
  • 针对该调试器会话评估表达式

大多数情况下,这样做的方式很难检测到应用程序实际上正在运行。但有时应用程序的副作用会显示出来并揭示幕后的真实情况。

编辑

一般来说,它不应该显示 UI。我可以想到一些晦涩的极端情况,虽然这种情况会发生,但不是 Visual Studio 错误。基本上都归结为相同的情况

评估的字符串会导致意外的副作用发生在正常程序流程中不会发生的时间。

这实际上比您在即时窗口中所期望的更常见,因为它实际上是在乱序执行您的代码。new Mercury_Reports通常你在执行之前永远不会到达,Program.Main但在即时窗口中,这正是发生的事情。这可能会产生令人讨厌的影响,例如重新排序静态类型构造函数

以下是一些意想不到的后果,它们可以通过即时窗口表达式浮出水面

  • 导致类型被加载,从而导致它们的静态初始化程序运行
  • 更改静态初始化程序的运行顺序
  • 表达式的返回类型有一个ToString调试器执行的方法
  • 表达式的返回类型具有DebuggerDisplay调试器执行的值

在过去,我看到过静态构造函数案例导致 UI 显示。本质上是一个静态类型构造函数正在评估MainForm.Instance(一个惰性创建属性)。在正常的程序流程中,它被调用从Program.Main运行并且从那时起简单可用。在即时窗口中虽然Program.Main没有运行。但是正在执行的表达式无意中加载了该类型,因此显示了一个微不足道的属性 getter 的 UI。

这是一个非常模糊的极端案例。我想说最可能的原因是 Visual Studio 中的一个错误。调试是一件令人讨厌的事情,尤其是在执行实时代码时,这可能就是其中的一个症状。

于 2012-06-06T16:37:43.260 回答