In an attempt to pleasantly display a Dictionary
's content, I wrote this:
[assembly: DebuggerDisplay("{Key,nq} -> {Value,nq}", Target = typeof(KeyValuePair<,>))]
namespace test {
[DebuggerDisplay("{DebuggerDisplay,nq}")]
public class Thing {
private readonly int _num;
public string DebuggerDisplay => $"DBG: {_num}";
public Thing(int num) => _num = num;
}
public class Program {
static void Main(string[] args) {
var map = new Dictionary<string,Thing> {
["Foo"] = new Thing(1),
["Bar"] = new Thing(2),
};
}
}
}
And I would've expected to see in the debugger this:
Foo -> DBG: 1
Bar -> DBG: 2
But instead I see this:
Foo -> {test.Thing}
Bar -> {test.Thing}
It's worth noting that if I expand on of the KeyValuePair
s, I do see that:
Name | Value
--------+-------
Key | "Foo"
Value | DBG: 1
So the DebuggerDisplay
does work.
So the problem is how to display the content of a composite type in the main watch-list of the dictionary's content?
Though nested evaluation of DebuggerDisplay
does not work it is actually flexible enough to call any custom formatting method with parameters. So I would do it like this:
[assembly:DebuggerDisplay("{Key,nq} -> {MyNamespace.DebugHelper.DisplayValue(this.Value),nq}", Target = typeof(KeyValuePair<,>))]
Where debug helper can be an internal helper class:
internal static class DebugHelper
{
internal static string DisplayValue(object value)
{
switch (value)
{
case Thing thing:
return thing.DebuggerDisplay; // or even better just to format it here
default:
return value.ToString();
}
}
}