19

I'd like to get ToString() to display for a class under my control in debug mode.

It'd be nice if this was the first thing to show up when you hover over a variable with the mouse. Is there an attribute for this?

sgtz
  • 8,849
  • 9
  • 51
  • 91
  • 3
    maybe Tools / Options / Debugging / "Enable property evaluation and other implicit function calls" + "Call string-conversion function on objects in variables windows". – ToolmakerSteve Nov 16 '18 at 13:23
  • Something else to check, if your ToString method throws an exception, the debug locals won't use it (unless you force it using class attributes in the answers below). – Elaskanator Jan 24 '19 at 17:24

8 Answers8

33

Mark your class with

[System.Diagnostics.DebuggerDisplay("{ToString()}")]

Test:

[System.Diagnostics.DebuggerDisplay("{ToString()}")]
class MyClass
{
    private string _foo = "This is the text that will be displayed at debugging"

    public override string ToString()
    {
        return _foo;
    }
}

Now when you hover over a variable with the mouse it will show This is the text that will be displayed at debugging.

BJ Myers
  • 6,617
  • 6
  • 34
  • 50
Jalal Said
  • 15,906
  • 7
  • 45
  • 68
10

There is DebuggerDisplayAttribute which lets you influence the display. It allows you to write fairly complex expressions to produce the debug output, although it is not recommended to do so.

However, if you have overriden ToString then the debugger is documented to display that by default. Maybe there's something wrong with the code?

Jon
  • 428,835
  • 81
  • 738
  • 806
  • +1 not sure what they meant by implicit access, but I'll keep those performance issues in mind. "If the expression references properties, attributes on those properties are not processed" is probably the biggest thing to wary of for me. – sgtz Jul 26 '11 at 11:39
  • @sgtz: They mean that `this` is available to use in the expression ("has access"), and you do not have to type it ("implicit"). Basically exactly what happens with `this` e.g. inside a class method. – Jon Jul 26 '11 at 11:52
  • 4
    If the `ToString()` throws an **exception** then VS debugger will not display the value. The `DebuggerDisplayAttribute` will force the display of the exception message. But normally you shouldn't need to do this. – swdev Oct 03 '15 at 08:39
  • Do you know why the debugger stop showing the toString() of my Collection when I add more than two elements, by any chance? – Ed_ Nov 07 '16 at 14:51
7

The output of ToString should be the default you see when debugging.

It can be overridden using the DebuggerDisplay Attribute (see MSDN).

I prefer overriding the ToString method because its easier and more versatile because it helps when writing to log files as well.

What output do you see? If you get the type name you see the default ToString.

Zebi
  • 8,682
  • 1
  • 36
  • 42
5

I had a similar issue. My class had an ToString() override and it still didn't show up in VS, which was odd.

Adding the attribute [System.Diagnostics.DebuggerDisplay("{ToString()}")] to the class showed an exception in the visual studio debugger, where the ToString should have displayed. Turned out I had a bug with incorrectly using string.Format() in my implementation. This is an interesting behavior - VS reverts to the default ToString in case of an exception. The usage of the mentioned attribute forces the display to show the method's output - valid or exception. This is very useful for debugging ToString(). Otherwise there is no point in adding this attribute explicitly to each class since classes have it turned on by default, unless one wants to turn this behavior off for some reason.

BigMan73
  • 1,344
  • 15
  • 14
4

What you are looking for is the DebuggerDisplayAttribute:

http://www.codeproject.com/Articles/117477/Using-DebuggerDisplayAttribute

Use the above link to see how it's done and then apply this to your class, using the ToString() method to drive what is shown. I've only ever used properties, not sure if you can inject classes.

Adam Houldsworth
  • 63,413
  • 11
  • 150
  • 187
  • +1 can only accept one answer, but this link give me an immediate example on what is possible. – sgtz Jul 26 '11 at 11:41
2

in the object Override the .ToString as follows:

public class MyObject
{
        public int Property1{ get; set; }
        public string Property2{ get; set; }
        public string Property3 { get; set; }

        public override string ToString()
        {
            return Property3;
        }
}

This will return Property3 as the ToString() value

stack72
  • 8,198
  • 1
  • 31
  • 35
0

If you are using visual studio you could add a watch @ runtime om the yourvariable.ToString() line, this will show up in the bottom of your screen when it hits a breakpoint

Thomas
  • 595
  • 1
  • 5
  • 20
  • 1
    While adding a watch variable serves its purpose, it does not answer the question. The question was how to make your variable display a tooltip when you hover over it in debug mode. – John C Oct 15 '12 at 04:23
0

My problem was that although I overrided the ToString() method in a class, the debugger still did not show the ToString() contents. The reason was that the base class already had a DebuggerDisplay attribute and this one took precedence over the ToString() method of the derived class. The solution was to add the DebuggerDisplay attribute to the derived class, too:

[DebuggerDisplay("Name: {Name}")]
class Base
{
    public string Name { get; set; }
}

// Add this line to show the Address instead of Name in the debugger.
[DebuggerDisplay("{ToString()}")]
class Derived : Base
{
    public string Address { get; set; }

    public override string ToString()
    {
        return $"Address: {Address}";
    }
}
Mustafa Özçetin
  • 1,893
  • 1
  • 14
  • 16