2

I am looking for a good concrete example where it is clearly desirable to override ToString() with something, but to use a [DebuggerDisplay(...)] custom attribute to display something else in the debugger?

Timwi
  • 65,159
  • 33
  • 165
  • 230

4 Answers4

7

Say, for example, a Node object for a binary tree.

The ToString() would merely want to display the payload for that node, while the DebuggerDisplay would probably also show which nodes it was pointing to.

James Curran
  • 101,701
  • 37
  • 181
  • 258
2

You can add also note that ToString() is not evaluated by the debugger in VB.NET. So if you plan on developing with several languages, getting used to this attributes in a good idea. It is stated on the MSDN page: https://msdn.microsoft.com/en-us/library/x810d419.aspx

Whether the debugger evaluates this implicit ToString() call depends on a user setting in the Tools / Options / Debugging dialog box . Visual Basic does not implement this implicit ToString() evaluation.

I prefer to use this attribute over the ToString because suppose I don't need to use the ToString() method for anything else, I don't like the idea of having a method sitting there for nothing.

And if you need another reason, I think it makes more sense to use a declarative approach because the debugger display string is just some metadata, it could also be used by some other tools.

Johann Blais
  • 9,389
  • 6
  • 45
  • 65
  • This is factually incorrect. If no `[DebuggerDisplay(...)]` attribute is present. the debugger *does* evaluate `ToString()`. – Timwi Mar 21 '17 at 16:50
  • @Timwi: up to VS 2015, it is stated on the MSDN page. No info for VS 2017. I have clarified that in my answer. – Johann Blais Mar 21 '17 at 18:27
1

Suppose you have an existing application where .ToString() is expected to, say, serialize the object to a string. Not that it's a good idea, but suppose you're in that situation. You could then still use [DebuggerDisplay(...)] to make your life easier, without modifying this (admittedly bad, but I suspect not unusual) contract between the class and the rest of the application.

Roman Starkov
  • 59,298
  • 38
  • 251
  • 324
  • XElement.ToString() is a similar case. Though viewing the XML in the debugger is presumably what you want anyway. – Kirk Woll Sep 13 '10 at 19:05
1

Lazy in .NET4 uses it to display important properties in debug:

[Serializable, 
DebuggerDisplay("ThreadSafetyMode={Mode}, IsValueCreated={IsValueCreated}, IsValueFaulted={IsValueFaulted}, Value={ValueForDebugDisplay}"), 
DebuggerTypeProxy(typeof(System_LazyDebugView<>)), ComVisible(false), HostProtection(SecurityAction.LinkDemand, Synchronization=true, ExternalThreading=true)]
public class Lazy<T>
{
...
}

ArrayList also use:

    [Serializable, ComVisible(true), DebuggerTypeProxy(typeof(ArrayListDebugView)), 
DebuggerDisplay("Count = {Count}")]
    public class ArrayList : IList, ICollection, IEnumerable, ICloneable
    {
    ...
    }

Or Color structure:

    [Serializable, StructLayout(LayoutKind.Sequential), TypeConverter(typeof(ColorConverter)), 
DebuggerDisplay("{NameAndARGBValue}"), 
Editor("System.Drawing.Design.ColorEditor, System.Drawing.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))]
    public struct Color
    {
    ...
    }

You can see it by using .NET Reflector tool.

SeeSharp
  • 1,730
  • 11
  • 31