Sophisticated debugging in .NET
December 18th, 2007Every programmer must sometimes use a debugger
In fact, most of our job is filled with debugging rather than writing code.
In the .NET framework there are many great features we can use to make us life easier. Today I am gonna present you a few very useful things from System.Diagnostics namespace.
Debugger class:
This is a class which allows us a communication with a attached debugger. It has multiple members but there are 3 of them I want you to notice.:
- Break - It just sends a break signal to a debugger. Very useful when we want to conditionally stop the execution of our application
- Launch - It can launch a debugger and attach it to a process
- Log - It posts a message to the attached debugger
IMHO, the most useful of those three methods is Break. Priceless when we have an unexpected situation in a code. Thanks to this method we are able to break an execution of a program. Look at this snippet:
-
object foo = Bar.GetSomething();
-
if(foo == null)
-
{
-
Debugger.Break();
-
}
Cool, isn't it?
Debug class:
Another good class which provides us helper methods in debugging process. Noticeable are:
- Assert - Evaluates a condition and displays a message if a condition is false. Well known for a "test driven" programmers.
- Fail - Outputs a failure message. Quite similar to the previous one but it doesn't evaluate an expression.
- Indent and Unident - useful for output formatting.
- Write, WriteLine and Print - write information to the Debug / Trace listeners
- WriteIf, WriteLineIf - The same as above but only when specified condition is met
Ok, those classes are in fact primitive but here is something that is very useful in debugging complex hierarchical objects.
Ladies and Gentleman - please welcome Debug attributes. Thanks to them a developer is able to declaratively specify how an application should behave during debugging process.
Let's say that you do not want a debugger step into a piece of code (because it's tested and works well) - no problem, there is DebuggerHiddenAttribute. Actually it stops a breakpoint from being set inside anything that it decorates.
-
class Foo
-
{
-
[DebuggerHidden()]
-
public void Bar()
-
{
-
// impossible to debug here
-
}
-
}
Let's say that we want to determine how a class or a property is displayed in a debugger window. There are two other attributes: DebuggerBrowsableAttribute and DebuggerDisplayAttribute. This code will do a trick with local variable / watch window in Visual Studio:
-
[DebuggerDisplay("Our Foo class")]
-
class Foo
-
{
-
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
-
private int _bar = 10;
-
-
[DebuggerDisplay("Value of Bar is: {_bar}")]
-
public int Bar
-
{
-
get
-
{
-
return _bar;
-
}
-
}
-
}
and a debugger view:
Nice
You can ofcourse set some parameters to those attributes. There are more attributes such as DebuggerStepThroughAttribute but I recommend further reading on MSDN.



Doesn’t ToString() work similar to DebuggerDisplay…? For example, in NetBeans (Java) you have to write toString() if you want to see anything about your custom object while debugging.
Yes it does, but ToString() was created for other purposes. It can be used for example in exception logging when additional data is needed. It is also used by many internal mechanisms in .NET.