Adam
Adam

Reputation: 2676

Running multiple lines on the immediate window in Visual Studio with C#

Is there a way to run multiple commands in a single entry in the immediate window of Visual Studio? I am running Visual Studio 2013.

I have a problem that is much easier to debug when I can create an input object within the immediate window and step through, but every time I make a change to the code I have to recreate the object like this:

var inputObject = new InputObject();
inputObject.Property1 = "value";
inputObject.Property2 = "value";
inputObject.Property3 = "value";
//etc.

It's a pain to have to rebuild this object by running each line individually to help debug this problem I have. Is there a way to run them all in one command? Something like this (though obviously this does not work):

var inputObject = new InputObject(); inputObject.Property1 = "value"; inputObject.Property2 = "value"; inputObject.Property3 = "value";

I do see that it is possible in Visual Basic from this link: Using colons to put two statements on the same line in Visual Basic

Any suggestions for other approaches to achieve the end goal are also welcome.

Upvotes: 7

Views: 6207

Answers (4)

Michael Bahig
Michael Bahig

Reputation: 766

Actually it does work, probably because I am writing this answer 5 years after this question was written. You see below I have declared a local var in the Immediate window then pressed Enter and used it in a later line in the Immediate window. I am using Visual Studio v.16.11.6

multiple lines in immediate window

Upvotes: 0

Caius Jard
Caius Jard

Reputation: 74680

If these were just props of the same class I'd go like ChristopherGLewis's answer

You can run multiple disparate assignments (i.e. setting props in different classes, or assigning unrelated variables) by stuffing them into an array all on the same line; don't forget that assignments in c# return values...

new object[]{ some.Prop1 = "hello", other.Prop2 = "goodbye", third.Prop3 = GetSomeValue(), myArray[0] = 2, _timeNow = DateTime.Now }

You get an object array back (and immed dumps it to the window), but as part of creating the array, immed ran the statements..

some.Prop1 = "hello";
other.Prop3 = "goodbye";
third.Prop3 = GetSomeValue();
myArray[0] = 2;
_timeNow = DateTime.Now;

..captured their return values, and put them in the array. As a side effect of each evaluation, the assignments you wanted made, were done - you probably don't care about the return values


I don't know of a way to do this with voids (i.e. I don't know how to make the immed window run 2 void methods on a single line); everything I've tried responds with calls into native method Microsoft.Win32.Win32Native.GetStdHandle(int). Evaluation of native methods in this context is not supported

//doesn't work
new [] {(Action)(() => { Console.WriteLine("a"); Console.WriteLine("b"); })}.ToList().ForEach(x => x())

Upvotes: 2

David Anderson
David Anderson

Reputation: 13680

In short, no. I don't believe the Immediate Window supports multiple statements at this time.

edit -- @Christopher_G_Lewis is actually correct, you can declare and instantiate new variables, but I found that the statement must be terminated with a semi-colon, unlike many other expressions that may be evaluated without one.

What you are doing comes across as a difficult method of debugging. If you have an issue that is difficult to debug without conventional methods (e.g. stepping through code, breakpoints, tracing) you should consider a Debugging Aid.

Debugging aids can vary, but why not just actually compile in that small snippet of code temporarily to help you troubleshoot the problem? The Immediate Window in Visual Studio isn't really intended to create control flow or new objects on demand, but is more designed for executing simple statements and expressions for quick analysis.

Your example is a bit vague to recommend a specific approach though, and I'm unsure what you are actually trying to accomplish. A simple struct in your code would still allow you to use it via the Immediate Window, and if you are concerned about accidentally leaving it in code you can use a #DEBUG constant to ensure it doesn't get compiled into your release configurations.

#if DEBUG
struct DebuggingAid
{
    public string A;
    public string B;
    public string C;
}
#endif

#if DEBUG
public void f()
{
    var aid = new DebuggingAid { A = "TestValue1", B = "TestValue2" };

    // var real data

    MethodBeingDebuggedWithStubDebuggingAidData(aid.A, A.B);
}
#endif

I would definitely consider different debugging methods that are available to you though.

  • Breakpoints are more powerful than you might realize. You can set conditional statements and also print out information when a breakpoint is hit and even call functions.
  • Function Breakpoints allow you break on a method of a particular name in the event you can't track down when it might be called, or where it is called from. You can also set conditions and actions.
  • Tracing with System.Diagnostics.Debug and System.Diagnostics.Trace to assist in debugger output in the IDE, you can also write traces to files.
  • Debugging aids, as already shown, and remove them from your code when you're done, or leave them in but compiled out #if DEBUG.
  • Unit testing - There is no wrong time to add a unit test to your code base. You will need to refactor your code slightly to facilitate testability, such as passing in dependencies, which it may appear that is what you are trying to do? (stubbing in test values to something?).
  • Immediate Window, by just manipulating the real data you are trying to (stub?) rather than creating debugging aids or test objects

If you could provide a little more detail about what you are trying to accomplish it will be a bit easier to provide some guidance, but hopefully this has helped you.

Upvotes: 4

Christopher G. Lewis
Christopher G. Lewis

Reputation: 4835

Actually its pretty simple to initiate an object in the immediate window:

inputObject = new InputObject()
{TestMVC.Areas.UI.Controllers.ServersController.InputObject}
    Property1: null
    Property2: null
    Property3: null

inputObject = new InputObject() {Property1 = "1", Property2 ="2", Property3 = "3"}
{TestMVC.Areas.UI.Controllers.ServersController.InputObject}
    Property1: "1"
    Property2: "2"
    Property3: "3"

But this is still a single command. Multiple commands are not supported.

Upvotes: 2

Related Questions