Использование атрибута DebuggerDisplay
Обновлен: Ноябрь 2007
Этот раздел применим для следующих версий.
Версия |
Visual Basic |
C# |
C++ |
Web Developer |
---|---|---|---|---|
Экспресс-выпуск |
||||
Standard |
||||
Pro и Team |
Условные обозначения:
Применимо |
|
Неприменимо |
|
Команда или команды по умолчанию скрыты. |
Атрибут DebuggerDisplay (System.Diagnostics.DebuggerDisplayAttribute) управляет тем, как класс или поле отображается в окнах переменных отладчика. Этот атрибут может применяться для:
Классы
Структуры
Делегаты
Перечисленения
Поля
Свойствами
сборок.
Атрибут DebuggerDisplay имеет один аргумент, который является строкой, он отображается в столбце "значение" для экземпляров типа. Эта строка может содержать фигурные скобки ({ и }). Текст в паре фигурных скобок будет вычисляться как поле, свойство или метод.
В коде C# можно использовать общее выражение между фигурными скобками. Выражение имеет неявный доступ к указателю this для текущего экземпляра только конечного типа. Выражение не имеет доступа к псевдонимам, локальным переменным или указателям. Если выражение ссылается на свойства, то атрибуты для этих свойств не обрабатываются.
Если в C# объект был переопределен ToString(), то отладчик вызовет переопределение и отобразит результат вместо стандартного {<typeName>}. Таким образом, если переопределен ToString(), то нет необходимости использовать DebuggerDisplay. Если используется и то, и другое, то атрибут DebuggerDisplay будет иметь более высокий преоритет по отношению к переопределению ToString().
Выполнит ли отладчик этот неявный вызов ToString() , или нет - зависит от параметров пользователя в диалоговом окне Параметры (категория Отладка, страница Общие). Visual Basic не выполняет это неявное вычисление ToString().
В следующей таблице показаны некоторые возможные способы использования атрибута DebuggerDisplay и пример выводов.
Атрибут |
Вывод, появляющийся в столбце Значение) |
---|---|
[DebuggerDisplay("x = {x} y = {y}")] Используется на типе с полями и x и y. |
x = 5 y = 18 |
[DebuggerDisplay("String value is {getString()}")] Синтаксис параметра может различаться в зависимости от языка. Поэтому используйте его с осторожностью. |
String value is [5, 6, 6] |
[DebuggerDisplay("Object {count - 2}: {(flag) ? \"yes\" : \"no\"}")] Синтаксис выражений зависит от используемого языка. Поэтому используйте его с осторожностью. |
Object 6: yes |
[DebuggerDisplay("Last = {_lastName,nq} {_var == null ? \"\" : \"First = \" + _firstName,nq}")] ,nq снимает знаки ковычек. |
Если присутствует фамилия Last = lastname First = firstname иначе: Last = lastname |
DebuggerDisplay может также принимать именованные параметры.
Параметры |
Назначение |
---|---|
Name, Type |
Эти параметры влияют на столбцы Имя и Тип окна переменных. (Они могут быть установлены в строки, используя тот же синтаксис, что и конструктор.) Злоупотребление этими параметрами, или их неправильное использование, может привести к конфликтам на выходе. |
Target, TargetTypeName |
Указывает конечный тип, когда атрибут используется на уровне сборки. |
Примечание. |
---|
Файл autoexp.cs использует атрибут DebuggerDisplay на уровне сборки. Файл autoexp.cs определяет расширения по умолчанию, которые Visual Studio использует для переменных C#. Можно проверить файл autoexp.cs на примерах способов использования атрибута DebuggerDisplay, или можно изменить и скомпилировать файл autoexp.cs чтобы изменить расширения по умолчанию. Не забудьте сделать резервную копию файла autoexp.cs прежде чем изменять его. Необходимо сделать ссылку на файл Microsoft.VisualStudio.DebuggerVisualizers.dll в \Program Files\Microsoft Visual Studio 9.0\Common7\IDE\PublicAssemblies. Файл autoexp.cs можно найти в папке My Documents/Visual Studio 9.0/Visualizers. |
Пример
В следующем примере показано, как использовать DebuggerDisplay, вместе с DebuggerBrowseable и DebuggerTypeProxy. При просмотре переменных в окнах отладчика, например в окне Контрольные значения, он формирует расширение, которые выглядит следующим образом:
Имя |
Значение |
Тип |
---|---|---|
Клавиша |
"три" |
объект {строка} |
Значение |
3 |
объект {целое} |
[DebuggerDisplay("{value}", Name = "{key}")]
internal class KeyValuePairs
{
private IDictionary dictionary;
private object key;
private object value;
public KeyValuePairs(IDictionary dictionary, object key, object value)
{
this.value = value;
this.key = key;
this.dictionary = dictionary;
}
public object Key
{
get { return key; }
set
{
object tempValue = dictionary[key];
dictionary.Remove(key);
key = value;
dictionary.Add(key, tempValue);
}
}
public object Value
{
get { return this.value; }
set
{
this.value = value;
dictionary[key] = this.value;
}
}
}
[DebuggerDisplay("Count = {hashtable.Count}")]
[DebuggerTypeProxy(typeof(HashtableDebugView))]
class MyHashtable
{
public Hashtable hashtable;
public MyHashtable()
{
hashtable = new Hashtable();
}
private class HashtableDebugView
{
private MyHashtable myhashtable;
public HashtableDebugView(MyHashtable myhashtable)
{
this.myhashtable = myhashtable;
}
[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
public KeyValuePairs[] Keys
{
get
{
KeyValuePairs[] keys = new KeyValuePairs[myhashtable.hashtable.Count];
int i = 0;
foreach (object key in myhashtable.hashtable.Keys)
{
keys[i] = new KeyValuePairs(myhashtable.hashtable, key, myhashtable.hashtable[key]);
i++;
}
return keys;
}
}
}
}
См. также
Основные понятия
Отображение пользовательских типов данных
Повышение эффективности отладки с помощью атрибутов просмотра отладчика