Customize debugger class display

Customize how classes are displayed when debugger

Home DailyDrop

Daily Knowledge Drop

The format of how classes are displayed in the debugger can be customized, using a numer of different methods.


Sample

All the samples below use an instance of the following simple entity class:

// class definition
public class Song
{
    public int Id { get; set; } 

    public string Name { get; set; }

    public string Artist { get; set; }

    public int YearReleased { get; set; }

    public int LengthInSeconds { get; set; }
}

// instance of the class
var song = new Song
{
    Id = 1,
    Name = "Everlong",
    Artist = "Foo Fighters",
    LengthInSeconds = 250,
    YearReleased = 1997
};

Default Display

By default, the output of a class in the debugger uses the ToString method on a class. The default for this method on a class is the class namespace and name.

The output in the Watch Window as well as when hovering the cursor over the instance:

Default output

ToString override

The first approach in customizing the output is to override the ToString method on the class:

public class Song
{
    //... existing class properties omitted

    // ToString method overridden and customized
    public override string ToString()
    {
        return $"Song `{Name}` by '{Artist} released " +
            $"in '{YearReleased}' and is '{LengthInSeconds}' seconds long";
    }
}

This overridden ToString method is now used:

ToString output


DebuggerDisplay attribute

In some use-cases, it might not be possible to use the ToString method, as it might be used in the functionality of the application in a specific format, and a different format is required for the debugger.

The next approach uses the DebuggerDisplay attribute - this is used to decorate the class with the format of the debugger display.

[DebuggerDisplay("{Name} by {Artist}")]
public class Song
{
    //... existing class properties omitted

    public override string ToString()
    {
        return $"Song `{Name}` by '{Artist} released " +
            $"in '{YearReleased}' and is '{LengthInSeconds}' seconds long";
    }
}

The display in the debugger now uses the DebuggerDisplay format, while explicitly using the ToString method will return the ToString method format.

DebuggerDisplay output


External classes

A 3rd party external class can also be targeted by the attribute.

Assume Song is now a external 3rd party class (which cannot be modified), and has no DebuggerDisplay attribute:

public class Song
{
    //... existing class properties omitted

    public override string ToString()
    {
        return $"Song `{Name}` by '{Artist} released " +
            $"in '{YearReleased}' and is '{LengthInSeconds}' seconds long";
    }
}

In the Program.cs startup file, the 'DebuggerDisplay` attribute is added with a specified Target:

[assembly: DebuggerDisplay("External: {Name} by {Artist}", Target = typeof(Song))]

var song = new Song
{
    Id = 1,
    Name = "Everlong",
    Artist = "Foo Fighters",
    LengthInSeconds = 250,
    YearReleased = 1997
};

Console.WriteLine(song);

The format specified by the DebuggerDisplay outside the class, is now used:

External DebuggerDisplay output


Notes

We've looked at a few useful ways in which the Visual Studio developer experience can be enhanced to improve the quality of life and productivity while working with a solution.

(The same might be experienced in Visual Studio Code and Rider, but it was not tested as part of this post)


References

Debug attributes in .NET

Daily Drop 26: 08-03-2022

At the start of 2022 I set myself the goal of learning one new coding related piece of knowledge a day.
It could be anything - some.NET / C# functionality I wasn't aware of, a design practice, a cool new coding technique, or just something I find interesting. It could be something I knew at one point but had forgotten, or something completely new, which I may or may never actually use.

The Daily Drop is a record of these pieces of knowledge - writing about and summarizing them helps re-enforce the information for myself, as well as potentially helps others learn something new as well.
c# .net debugger display debuggerdisplay tostring