Easier Debugging with Attributes

2007, Sep 05    

Unless you have been inspecting some of the code generated by Visual Studio, you probably haven't realized that there are several attributes that you can add to your code to make debugging easier. Some prevent you from stepping into sections of code, others change the way variables are displayed in the watch window.

The following are some of the more useful attributes found in the System.Diagnostics namespace.

DebuggerStepThrough

I don't know about you, but I hate it when I try to step into a method, but before I get there, I have to step into the getter for every property that is being passed in as a parameter. You have to step in/step out repeatedly until you end up in the method. Half the time, I end up missing it and step out of the method!

To prevent this dance, just add the DebuggerStepThrough attribute to the getter for your simple properties and the debugger will no longer step into them. This also works on methods and even entire classes.

public string Name
{
    [DebuggerStepThrough]
    get { return _name; }
    set { _name = value; }
}

DebuggerBrowsable

Do you want to simplify or change the way your class appears in the watch window? This attribute allows you to hide members and properties or even hide the root of a collection. DebugBrowsable is constructed with the DebuggerBrowsableState enum which has the following members;

Collapsed Show the element as collapsed.
Never Never show the element.
RootHidden Do not display the root element; display the child elements if the element is a collection or array of items.

For example, adding

[DebuggerBrowsable( DebuggerBrowsableState.Never )]

to the private members of a class will cause them to be hidden in the watch window, thus cleaning up the view.

DebuggerDisplay

DebuggerDisplay is my favourite attribute. Add it to a class and construct it with a string, and it will display that string in the watch window. Add any properties you want displayed within curly braces and they will automatically be substituted in. For example;

[DebuggerDisplay( "Name: {Name}, Age: {Age}" )]
public class Person
{
    // ...
}

These are the three attributes that I use most often, but you may also want to look up DebuggerStepperBoundary, DebuggerTypeProxy and DebuggerVisualizer.

Happy Debugging!