Equipping 3rd party types with debugging capabilities

1/13/2025
2 minute read

Debugging is important, and it's often useful to be able to inspect the state of objects in the debugger. However sometimes you're working with 3rd party types that don't have any debugging capabilities, so you can't see their internal state easily. In this blog post we will have a look on how to equip 3rd party types with debugging capabilities.

DebuggerDisplayAttribute to the rescue

The DebuggerDisplayAttribute is a very useful attribute that allows you to specify how an object should be displayed in the debugger. "Equipping" your own types as such:

[DebuggerDisplay("Name = {Name}, Age = {Age}")]
public class Person
{
    public required string Name { get; set; }
    public required int Age { get; set; }
}

var person = new Person { Name = "John", Age = 42 };

This will make the debugger display the Person object as Name = John, Age = 42. Cool, cool, cool. But what if you're working with a 3rd party type where you can't easily add the DebuggerDisplayAttribute? Well, what if I tell you, that you can?

Equipping 3rd party types with DebuggerDisplayAttribute

There is a lesser known property called Target which defines, which type the DebuggerDisplayAttribute should be applied to. We can use this in combination with the assembly attribute to equip any type with debugging capabilities. For the sake of keeping it easy, I will equip the Task type even though it already has debugging capabilities.

[assembly: DebuggerDisplay("Is Task finished: {IsCompleted}", Target = typeof(Task))]

var task = Task.Delay(100_000);
await task;

Now, hovering over the task object will result into:

Debugging

There are some "natural" downsides to this approach:

  • You can only use public types or interfaces for obvious reasons.
  • It might be not obvious where the debugging information is coming from. Especially if you have a deep dependency graph and someone in the middle is equipping a type with debugging capabilities.
An error has occurred. This application may no longer respond until reloaded. Reload x