Consider this MCVE class:
public class Foo<T>
{
private readonly T value;
public Foo(T value)
{
this.value = value;
}
}
When I evaluate and print such an object in C# Interactive, it looks like this:
> new Foo<string>("bar")
Foo<string> { }
That's not useful. I'd like it to look like this:
Foo<string> { "bar" }
How do I do that?
I've tried overriding ToString
like this:
public override string ToString()
{
return $"Foo{typeof(T)} {{ {value} }}";
}
This doesn't produce quite what I'd like:
> new Foo<string>("bar")
[Foo<System.String> { bar }]
There're at least three issues with this output:
"bar"
instead of bar
.System.String
instead of string
.Is there a way to make C# interactive display an object with a custom format?
I know that I can add a public property to the class in order to display the value, but I don't want to do that because of encapsulation concerns. To be clear, though, here's what I mean:
public class Foo<T>
{
public Foo(T value)
{
Value = value;
}
public T Value { get; }
}
This prints closer to what I'd like:
> new Foo<string>("bar")
Foo<string> { Value="bar" }
but, as I wrote, I don't want to add a public property.
How do I get it to behave like the following?
> new Foo<string>("bar")
Foo<string> { "bar" }
> new Foo<int>(42)
Foo<int> { 42 }
Notice that when using anything else than a string (e.g. an int
), there should be no quotes.
You could use the [DebuggerDisplay]
attribute to customize the object print. Beside overriding ToString()
, you can use any methods/properties in this attribute. For example:
[DebuggerDisplay("{GetDebuggerDisplay(), nq}")]
public class Foo<T>
{
private readonly T value;
public Foo(T value)
{
this.value = value;
}
private string GetDebuggerDisplay()
{
var val = value is string ? "\"" + value + "\"" : value?.ToString();
return $"Foo<{typeof(T).Name.ToLower()}> {{ {val} }}";
}
}
This avoids having to override ToString()
, or use a different implementation. Such as returning the string representation of T value
.
You'll need to add a switch/case to transform class names such as Int32
to int
.
The nq
part of the [DebuggerDisplay]
attribute removes the quotes around the value.
The result looks like:
> new Foo<string>("bar")
Foo<string> { "bar" }
For further reference, please check out the excellent blog post of Jared Parson about the [DebuggerDisplay]
attribute: https://blogs.msdn.microsoft.com/jaredpar/2011/03/18/debuggerdisplay-attribute-best-practices/.
If you're OK with overriding the ToString()
like in your first attempt, then you can do whatever you like there. This gets you closer to what you want and you can modify it as you see fit:
public override string ToString()
{
string v = value is string ? $"\"{value}\"" : $"{value}";
string t = typeof(T).Name.ToLower();
return $"Foo<{t}> {{ {v} }}";
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With