奇怪的行为:立即启动应用程序窗口,而不是评估表达式

时间:2012-06-06 16:34:07

标签: visual-studio

我不知道下面这段代码是真的相关,但为了完全公开,这里是我试图从立即窗口调用的代码:

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文件中。然后,不是像最后三次那样启动应用程序然后点击断点,而是决定实际只是评估我的表达。

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

1 个答案:

答案 0 :(得分:3)

在未调试时在立即窗口中计算表达式时,会发生以下过​​程

  • 将您的项目/应用程序二进制文件加载到托管过程中
  • 默认将调试程序附加到托管进程
  • 根据该调试器会话评估表达式

大多数情况下,这是以一种难以检测应用程序实际运行的方式完成的。但偶尔应用程序的副作用会显示出来,并揭示真正发生的事情。

修改

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

  

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

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

以下是一些可能通过即时窗口表达显示的意外后果

  • 导致类型被加载并因此导致其静态初始化程序运行
  • 更改运行静态初始化程序的顺序
  • 表达式的返回类型具有调试器执行的ToString方法
  • 表达式的返回类型具有调试器执行的DebuggerDisplay

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

这是一个相当模糊的角落案例。我想这里最可能的原因是Visual Studio中的一个错误。调试是令人讨厌的事情,特别是在执行实时代码时,这可能是一个症状。