mark
mark

Reputation: 62712

DebuggerDisplay attribute does not work as expected

I know that this attribute should work in C# and yet, in my case it does not. I have a class with a lazy property Children. Accessing this property may have a side effect of roundtripping to the server. So, naturally, I do not want this to happen when I just watch it in the debugger watch window.

Omitting all the irrelevant details the source looks pretty ordinary:

[DebuggerDisplay("(Frozen) {m_children}")]
public IList<IEntityBase> Children
{
  get
  {
    if (m_children == null)
    {
      m_children = FetchChildrenFromDB(this);
    }
    return m_children;
  }
}

And yet, when I watch the object and expand this in the watch window I do not see (Frozen) in the display, meaning the debugger simply ignores the attribute.

DebuggerDisplay image snapshot

The attribute is really there, according to Reflector. I use VS2008.

Any ideas?

Upvotes: 4

Views: 1927

Answers (5)

Artem Vertiy
Artem Vertiy

Reputation: 1118

When you pin a property in the Visual Studio debugger, it becomes the prioritized display item, effectively overriding [DebuggerDisplay]. This behavior lets you focus on specific fields but can indeed hide the custom display you set up with [DebuggerDisplay]

on the sceen i've pinned a Content property that's why Debugger shows it like Content = {....} instead of expected [DebuggerDisplay("RestResponse {ToString()})]

enter image description here

Upvotes: 0

PaulS
PaulS

Reputation: 709

If you are seeing in your watch window something along the lines of:

[+]  ObjectName    | { namespace.object}

Ensure that "Tools->Options->Debugging->General->Show raw structure of objects in variables windows" is NOT checked.

Once I cleared this, my DebuggerDisplay attributes displayed correctly (including showing all the "WTF"'s and "Huh"'s I'd added...)

Upvotes: 5

Laurent Etiemble
Laurent Etiemble

Reputation: 27889

You should put the DebuggerDisplayAttribute on the class and not on the property, because m_children is an instance field and cannot be evaluated in the property context.

The property display is always evaluated as is, because there is no debugger proxy for it.

Upvotes: 0

shahkalpesh
shahkalpesh

Reputation: 33476

I think, it could be due to brackets "(Frozen)".
Change it to "Frozen", if it is text.

BTW, what is "Frozen"? Is it a simple text or an existing property?
EDIT: This is what I guessed based on the example code on MSDN & Lasse's code.

Upvotes: 0

Lasse V. Karlsen
Lasse V. Karlsen

Reputation: 391276

Well, I just tested it and it works with my simple program. I also thought I had a possible explanation, but testing shows that it wasn't what I thought (info below code).

First, here's the code that works:

using System;
using System.Diagnostics;
using System.Collections.Generic;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Program p = new Program();
            Console.Out.WriteLine(p.Name); // breakpoint here
        }

        private String _Name = String.Empty;
        [DebuggerDisplay("Name: {_Name}")]
        public String Name
        {
            get { return _Name; }
            set { _Name = value; }
        }

        private IList<String> _Names = new List<String>();
        [DebuggerDisplay("Names: {_Names.Count}")]
        public IList<String> Names
        {
            get { return _Names; }
            set { _Names = value; }
        }
    }
}

What I thought was that the collection class that you retrieve from FetchChildrenFromDB method had its own DebuggerDisplay attribute attached to it, and it took priority. But that's not it. I implemented a dummy IList class with that attribute attached to it, and the one attached to the property still took priority.

Upvotes: 1

Related Questions