Debugging your .NET application more easily

As a programmer, you often have to debug your code, or the code written by a coworker. I don't like debugging, but as you know:

If debugging is the process of removing bugs, then programming must be the process of putting them in.

Unless you are extraordinary developer, you'll need to debug your code. Visual Studio provides great tools to help you in this task. The main features are breakpoints, step by step execution, and viewing the value of the variables:

By default, the debugger doesn't always show useful values. In the previous screenshot, you cannot quickly distinguish the 2 customer instances. Let's see how to improve that and thus, reduce the time needed to debug your application!

Override the ToString method

By default, the value of the ToString method is shown. So, the first way to change the display value is to override theToString method and return something more useful:

public class Customer
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public List<Order> Orders { get; } = new List<Order>();

    public override string ToString()
    {
        return $"{FirstName} {LastName}";
    }
}

Use the DebuggerDisplay attribute

When you don't want to override the ToString method just for debugging purpose, you can use the DebuggerDisplay attribute. The value of the attribute uses a format similar to the syntax introduced in C# 6 with string interpolation. However, the text between brackets are expressions to be evaluated by the debugger engine. So, an expression can be a property name or a more complex expression such as {Count > 0 ? Count : 0}.

[DebuggerDisplay("{Id} - {FullName} ({Orders.Count} orders)")]
public class Customer
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public List<Order> Orders { get; } = new List<Order>();

    public string FullName => $"{FirstName} {LastName}";
}

Evaluating an expression by the debugger is expensive, so you should not have to much expressions in the display value. Instead, you can create a private property in your class, and use only this property in the DebuggerDisplay attribute.

[DebuggerDisplay("{DebuggerDisplay,nq}")] // nq means no quote
public class Customer
{
    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    private string DebuggerDisplay => $"{Id} - {FullName} ({Orders.Count} orders)";
}

I use the nq format to prevent Visual Studio from adding quotes around the value. You'll find valid formats in the documentation.

Hide code to the debugger

You can annotate your code with some attributes to change the behavior of the debugger when you run step by step. For instance, you don't want the debugger to step into generated code. In this case, you can add one of the following attributes:

static void Main()
{
    GeneratedMethod(); // Step into...
}

[DebuggerNonUserCode]
private static void GeneratedMethod() // show as External Code in the call stack
{ // do not step here
    MyCode();
}

private static void MyCode()
{ // ... step here
}

The GeneratedMethod method is not visible in the call stack:

Call Stack with DebuggerNonUserCodeAttribute

Conclusion

The Visual Studio debugger is very great. It allows to quickly debug your code by using breakpoints, viewing the value of the variables, and more. You can customize it by adding some attributes in your code. These attributes should help you in reducing the time needed to debug your application.

Leave a reply