The Art of Debugging – A Developer’s Best Friend – Lesson 6 – Watch and Immediate Windows – Advanced Techniques - Repost
Calling Methods in the Watch Window
The watch window is incredibly powerful. You can actually call methods directly from this window. But note that that method call must execute within 20 seconds, or visual studio will assume that the method is hung and will cancel its execution.
Open source code to MainForm.cs and navigate to buttonWatchDemo_Click method and set a breakpoint on the "CallABunchMethod()" line.
Switch to the C# Breakpoints Demo window and click the Call A Bunch button.
After setting a breakpoint, go ahead and start debugging. At this point, we are ready to bring up the watch window. The watch window is available from the debug menu. Notice that there are up to four separate watch windows you can choose from.
Before we actually execute them that could from the watch window, let’s actually go and see what the method looks like. Notice that the method simply prints out messages to the output window. Depending on the result of the modulus operator we print different messages.
Notice that we’ve got full intellisense available. In this case we want to execute CallABunchMethod(). So select the method from the intellisense and hit the enter key. You’ll need to remember to add the parentheses however.
Notice that the output window is displaying the appropriate message –namely, that we have not hit in the value of five in our static variable. One thing to remember is that if we want to call this method more than once through the watch window, we need to erase it and re-type it.
The Immediate Window
The immediate window also offers similar capabilities. It should be familiar to those who have previously programmed in Visual Basic 6. You start all commands with a question mark as follows:
You can also execute methods from the immediate window. One thing to note is that break points are disregarded in the watch windows while breakpoints are adhered to in the immediate window. That means that if you set a breakpoint within a function call the debugger will stop there if you execute that method through the immediate window. The same is not true for the watch windows.
Another difference between the immediate windows and the watch windows is that method calls from the immediate windows can last as long as you wish them too. However, in the watch windows you only have 20 seconds two finish executing the method before the debugger abandons the call.
Using the watch window to help you do find test cases
The watch window allows you to a modify data directly. In the window below you can see the condition in the if statement. Currently it is a true statement. In order for me to make it a false statement I have to step through the debugger some more. But what I can do instead is change the static variable directly within the debugger to see the effect it has on the condition within the if statement.
Now I can go to the value column in the watch window and type in the number “1”. This will cause the condition in the if statement to become false. This gives me a quick and easy way to test my if statements without having to do endless stepping through the debugger.
This is a real straightforward way to change the state of my application without having to constantly re- run the application, testing various conditions during each run. This is a real big time saver. It also allows for easy test case generation. Scripting languages have had this for a while, but now we can take advantage of it for managed code as well.
How to create and replace a local object from the watch window or from the immediate window
Similar to the way we call the methods from the immediate and watch windows, we can also create objects, replacing existing objects within the stack frame.
Notice that we are about to pass a null populated object to the method called CallEvenMore(). Hitting the F11 key (single step) in the debugger ends up passing the ae object to the method called CallEvenMore().
Notice that in the function above, the AE object is in fact equal to null. Before single stepping one more time, we want to inject a new object called the x, except that we will not put in a null value – instead, we will populate this object with a real value.
This new object will appear in the locals window, preceded by the symbol “$”.
Using standard c# syntax, this can be done from the immediate window as follows:
Now, we can assign this $x variable to ae, allowing us to directly use the ae variable within the CallEvenMore() method. This is a useful technique which allows you to create new variables or objects on the fly. As you can see, we were able to test the string method called IsNullOrEmpty() without having to run the application multiple times. We simply created a new variable on the fly and assigned it to a local variable within the method, all from the immediate window.