Weird behaviour: Immediate Window starting app ins

2019-08-04 01:59发布

I don't know that the following piece of code is really relevant, but for the sake of full disclosure here is the code I was trying to call from the Immediate Window:

abstract class Test
{
    public int x;

    public Test()
    {
        x = 5; 
    }
}

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

It was just a test to see whether the default base constructor gets called automatically or if I have to call it specifically because I couldn't remember.

Okay, on to the problem. I typed this into the Immediate Window to see the result:

new Mercury_Reports.TestImp().GetX();

And rather than evaluating the expression it just started my application. I closed the app and tried again two more times and got the same result. The next time, I went and put a breakpoint in my Program.cs file. Then instead of starting the app like it did the last three times and then hitting the breakpoint, it decided to actually just evaluate my expression.

I've seen some weird things in the Visual Studio IDE before, but I think this is one of the weirdest. Anyone have a clue as to what was going on there? :)

1条回答
Rolldiameter
2楼-- · 2019-08-04 02:08

When evaluating an expression in the immediate window when you're not debugging the following process takes place

  • Loads your project / application binaries into the hosting process
  • Silently attaches the debugger to the hosting process
  • Evaluating the expression against that debugger session

Most of the time this is done in a way that makes it hard to detect that the application is actually being run. But occasionally a side effect of the application shows through and reveals what's really going on under the hood.

EDIT

In general it shouldn't be displaying the UI though. I can think of some obscure corner cases where this would happen though and not be a Visual Studio bug. The basically all come down to the same scenario though

The evaluated string causes an unintended side effect to happen at a time where it wouldn't happen during normal program flow.

This is actually more common than you'd expect in the immediate window because it's essentially executing your code out of order. Normally you'd never get to new Mercury_Reports before executing Program.Main but in the immediate window this is exactly what happens. This can have nasty effects like re-ordering static type constructors

Here are some unintended consequences which can surface via an immediate window expression

  • Cause types to be loaded and hence cause their static initializers to run
  • Change the order in which static initializers are run
  • The return type of the expression has a ToString method the debugger executes
  • The return type of the expression has a DebuggerDisplay value which the debugger executes

In the past I have seen the static constructor case cause UI to show. Essentially a static type constructor was evaluating MainForm.Instance (a lazy creation property). During normal program flow it was called from Program.Main was run and from then on was simply available. In the immediate window though Program.Main didn't run. But the expression being executed inadventently loaded that type and hence displayed the UI for what was a trivial property getter.

This is a pretty obscure corner case though. I'd say the most likely cause here is a bug in Visual Studio. Debugging is nasty business, especially when executing live code, and this is probably a symptom of that.

查看更多
登录 后发表回答