Атрибут DebuggerDisplay не работает должным образом!
Я знаю, что этот атрибут должен работать в C#, и все же, в моем случае это не так. У меня класс с ленивым свойством Дети. Доступ к этому свойству может иметь побочный эффект при обращении к серверу. Поэтому, естественно, я не хочу, чтобы это происходило, когда я просто смотрю это в окне просмотра отладчика.
Опуская все несущественные детали, источник выглядит довольно обыденно:
[DebuggerDisplay("(Frozen) {m_children}")]
public IList<IEntityBase> Children
{
get
{
if (m_children == null)
{
m_children = FetchChildrenFromDB(this);
}
return m_children;
}
}
И все же, когда я наблюдаю за объектом и раскрываю this
в окне просмотра я не вижу (заморожено) на дисплее, то есть отладчик просто игнорирует атрибут.
Если ссылка на изображение все еще действительна, она должна быть видна ниже: http://i28.tinypic.com/2zxo9s5.jpg http://i28.tinypic.com/2zxo9s5.jpg
Атрибут действительно есть, согласно Reflector. Я использую VS2008.
Есть идеи?
4 ответа
Если вы видите в окне просмотра что-то вроде:
[+] ObjectName | { namespace.object}
Убедитесь, что "Инструменты-> Параметры-> Отладка-> Общие-> Показать необработанную структуру объектов в окнах переменных" НЕ отмечены.
Как только я очистил это, мои атрибуты DebuggerDisplay отображались правильно (включая отображение всех "WTF" и "Huh", которые я добавил...)
Ну, я только что проверил это, и это работает с моей простой программой. Я также думал, что у меня есть возможное объяснение, но тестирование показывает, что это не то, что я думал (информация ниже кода).
Во-первых, вот код, который работает:
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; }
}
}
}
Я думал, что класс коллекции, который вы извлекаете из метода FetchChildrenFromDB, имеет свой собственный атрибут DebuggerDisplay, и он имеет приоритет. Но это не так. Я реализовал фиктивный класс IList с прикрепленным к нему атрибутом, а тот, который был присоединен к свойству, по-прежнему имел приоритет.
Я думаю, это может быть из-за скобок "(заморожено)".
Измените его на "Замороженный", если это текст.
Кстати, что такое "замороженный"? Это простой текст или существующее свойство?
РЕДАКТИРОВАТЬ: Это то, что я догадался на основе примера кода на MSDN и код Лассе.
Вы должны поместить DebuggerDisplayAttribute в класс, а не в свойство, потому что m_children
является полем экземпляра и не может оцениваться в контексте свойства.
Отображение свойства всегда оценивается как есть, поскольку для него нет прокси-сервера отладчика.