Заметка
Доступ к этой странице требует авторизации. Вы можете попробовать войти в систему или изменить каталог.
Доступ к этой странице требует авторизации. Вы можете попробовать сменить директорию.
Замечание
Эта статья связана с .NET Framework. Он не применяется к более новым реализациям .NET, включая .NET 6 и более поздние версии.
Атрибуты отображения отладчика позволяют разработчику типа, который указывает и лучше понимает поведение этого типа в среде выполнения, также определить, как этот тип будет выглядеть при отображении в отладчике. Кроме того, атрибуты отображения отладчика, которые предоставляют свойство Target, пользователи могут применять на уровне сборки без знания исходного кода. Атрибут DebuggerDisplayAttribute управляет отображением типа или члена в окнах переменных отладчика. Атрибут DebuggerBrowsableAttribute определяет, отображается ли поле или свойство в окнах переменных отладчика. Атрибут DebuggerTypeProxyAttribute задает замещающий тип или прокси-сервер для типа и изменяет способ отображения типа в окнах отладчика. При просмотре переменной, имеющей прокси или тип замены, прокси заменяет исходный тип в окне отображения отладчика. В окне переменной отладчика отображаются только общедоступные члены типа прокси-сервера. Приватные члены не отображаются.
Использование отладчикаDisplayAttribute
Конструктор DebuggerDisplayAttribute имеет один аргумент: строка, отображаемая в столбце значений для экземпляров типа. Эта строка может содержать фигурные скобки ({ и }). Текст в паре фигурных скобок оценивается как выражение. Например, следующий код C# приводит к отображению "Count = 4" при выборе знака плюса (+) для расширения отображения отладчика для экземпляра MyHashtable.
[DebuggerDisplay("Count = {count}")]
class MyHashtable
{
public int count = 4;
}
Атрибуты, применяемые к свойствам, на которые ссылается выражение, не обрабатываются. Для компилятора C# допускается общее выражение, которое имеет только неявный доступ к этой ссылке для текущего экземпляра целевого типа. Выражение ограничено; нет доступа к псевдонимам, локальным переменным или указателям. В коде C# можно использовать общее выражение между фигурными скобками с неявным доступом к this указателю только для текущего экземпляра целевого типа.
Например, если объект C# переопределен ToString(), отладчик вызовет переопределение и отобразит его результат вместо стандартного {<typeName>}. , если вы переопределили ToString(), вам не нужно использовать DebuggerDisplayAttribute. Если вы используете и то, и другое, атрибут DebuggerDisplayAttribute имеет приоритет над переопределением ToString().
Использование отладчикаBrowsableAttribute
DebuggerBrowsableAttribute Примените его к полю или свойству, чтобы указать, как поле или свойство должно отображаться в окне отладчика. Конструктор для этого атрибута принимает одно из DebuggerBrowsableState значений перечисления, которое указывает одно из следующих состояний:
Never указывает, что элемент не отображается в окне данных. Например, если использовать это значение для DebuggerBrowsableAttribute в поле, оно удаляется из иерархии; поле не отображается, когда вы разворачиваете тип, нажав на знак плюса (+) для экземпляра типа.
Collapsed указывает, что элемент отображается, но не расширяется по умолчанию. Это поведение по умолчанию.
RootHidden указывает, что сам элемент не отображается, но его составляющие объекты отображаются, если это массив или коллекция.
Замечание
DebuggerBrowsableAttribute не поддерживается в Visual Basic в версии 2.0 .NET Framework.
Следующий пример кода показывает использование DebuggerBrowsableAttribute, чтобы предотвратить отображение следующего за ним свойства в окне отладки для класса.
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
public static string y = "Test String";
Использование отладчикаTypeProxy
DebuggerTypeProxyAttribute Используйте атрибут, если необходимо значительно и принципиально изменить представление отладки типа, но не измените сам тип. Атрибут DebuggerTypeProxyAttribute используется для указания прокси-сервера отображения для типа, что позволяет разработчику адаптировать представление для типа. Этот атрибут, например DebuggerDisplayAttribute, можно использовать на уровне сборки, в этом случае Target свойство указывает тип, для которого будет использоваться прокси-сервер. Рекомендуемое использование заключается в том, что этот атрибут указывает частный вложенный тип, который возникает в пределах типа, к которому применяется атрибут. Средство оценки выражений, поддерживающее средства просмотра типов, проверяет наличие этого атрибута при отображении типа. Если атрибут найден, средство оценки выражений заменяет тип прокси отображения для типа, к которому применяется атрибут.
Когда присутствует DebuggerTypeProxyAttribute, окно переменных отладчика отображает только публичные члены типа прокси. Приватные члены не отображаются. Поведение окна данных не изменяется с помощью расширенных атрибутов представлений.
Чтобы избежать ненужных потерь производительности, атрибуты прокси отображения не обрабатываются, пока объект не будет развернут: либо когда пользователь щелкает по знаку плюса (+) рядом с типом в окне данных, либо с помощью применения атрибута DebuggerBrowsableAttribute. Поэтому рекомендуется не применять атрибуты к типу отображения. Атрибуты могут и должны применяться в рамках типа отображения.
В следующем примере кода показано использование DebuggerTypeProxyAttribute для указания типа, который будет использоваться как прокси отображения отладчика.
[DebuggerTypeProxy(typeof(HashtableDebugView))]
class MyHashtable : Hashtable
{
private const string TestString =
"This should not appear in the debug window.";
internal class HashtableDebugView
{
private Hashtable hashtable;
public const string TestStringProxy =
"This should appear in the debug window.";
// The constructor for the type proxy class must have a
// constructor that takes the target type as a parameter.
public HashtableDebugView(Hashtable hashtable)
{
this.hashtable = hashtable;
}
}
}
Пример
Описание
Следующий пример кода можно просмотреть в Visual Studio, чтобы увидеть результаты применения атрибутов DebuggerDisplayAttribute, DebuggerBrowsableAttribute, и DebuggerTypeProxyAttribute.
Код
using namespace System;
using namespace System::Collections;
using namespace System::Diagnostics;
using namespace System::Reflection;
ref class HashtableDebugView;
[DebuggerDisplay("{value}", Name = "{key}")]
ref class KeyValuePairs
{
private:
IDictionary^ dictionary;
Object^ key;
Object^ value;
public:
KeyValuePairs(IDictionary^ dictionary, Object^ key, Object^ value)
{
this->value = value;
this->key = key;
this->dictionary = dictionary;
}
};
[DebuggerDisplay("Count = {Count}")]
[DebuggerTypeProxy(HashtableDebugView::typeid)]
ref class MyHashtable : Hashtable
{
private:
static const String^ TestString = "This should not appear in the debug window.";
internal:
ref class HashtableDebugView
{
private:
Hashtable^ hashtable;
public:
static const String^ TestString = "This should appear in the debug window.";
HashtableDebugView(Hashtable^ hashtable)
{
this->hashtable = hashtable;
}
[DebuggerBrowsable(DebuggerBrowsableState::RootHidden)]
property array<KeyValuePairs^>^ Keys
{
array<KeyValuePairs^>^ get()
{
array<KeyValuePairs^>^ keys = gcnew array<KeyValuePairs^>(hashtable->Count);
IEnumerator^ ie = hashtable->Keys->GetEnumerator();
int i = 0;
Object^ key;
while (ie->MoveNext())
{
key = ie->Current;
keys[i] = gcnew KeyValuePairs(hashtable, key, hashtable[key]);
i++;
}
return keys;
}
}
};
};
public ref class DebugViewTest
{
private:
// The following constant will appear in the debug window for DebugViewTest.
static const String^ TabString = " ";
public:
// The following DebuggerBrowsableAttribute prevents the property following it
// from appearing in the debug window for the class.
[DebuggerBrowsable(DebuggerBrowsableState::Never)]
static String^ y = "Test String";
static void Main()
{
MyHashtable^ myHashTable = gcnew MyHashtable();
myHashTable->Add("one", 1);
myHashTable->Add("two", 2);
Console::WriteLine(myHashTable->ToString());
Console::WriteLine("In Main.");
}
};
int main()
{
DebugViewTest::Main();
}
using System;
using System.Collections;
using System.Diagnostics;
using System.Reflection;
class DebugViewTest
{
// The following constant will appear in the debug window for DebugViewTest.
const string TabString = " ";
// The following DebuggerBrowsableAttribute prevents the property following it
// from appearing in the debug window for the class.
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
public static string y = "Test String";
static void Main()
{
MyHashtable myHashTable = new MyHashtable();
myHashTable.Add("one", 1);
myHashTable.Add("two", 2);
Console.WriteLine(myHashTable.ToString());
Console.WriteLine("In Main.");
}
}
[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;
}
}
[DebuggerDisplay("Count = {Count}")]
[DebuggerTypeProxy(typeof(HashtableDebugView))]
class MyHashtable : Hashtable
{
private const string TestString = "This should not appear in the debug window.";
internal class HashtableDebugView
{
private Hashtable hashtable;
public const string TestString = "This should appear in the debug window.";
public HashtableDebugView(Hashtable hashtable)
{
this.hashtable = hashtable;
}
[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
public KeyValuePairs[] Keys
{
get
{
KeyValuePairs[] keys = new KeyValuePairs[hashtable.Count];
int i = 0;
foreach(object key in hashtable.Keys)
{
keys[i] = new KeyValuePairs(hashtable, key, hashtable[key]);
i++;
}
return keys;
}
}
}
}
Imports System.Collections
Imports System.Diagnostics
Imports System.Reflection
Class DebugViewTest
' The following constant will appear in the debug window for DebugViewTest.
Const TabString As String = " "
' The following DebuggerBrowsableAttribute prevents the property following it
' from appearing in the debug window for the class.
<DebuggerBrowsable(DebuggerBrowsableState.Never)> _
Public Shared y As String = "Test String"
Shared Sub Main()
Dim myHashTable As New MyHashtable()
myHashTable.Add("one", 1)
myHashTable.Add("two", 2)
Console.WriteLine(myHashTable.ToString())
Console.WriteLine("In Main.")
End Sub
End Class
<DebuggerDisplay("{value}", Name:="{key}")> _
Friend Class KeyValuePairs
Private dictionary As IDictionary
Private key As Object
Private value As Object
Public Sub New(ByVal dictionary As IDictionary, ByVal key As Object, ByVal value As Object)
Me.value = value
Me.key = key
Me.dictionary = dictionary
End Sub
End Class
<DebuggerDisplay("Count = {Count}"), DebuggerTypeProxy(GetType(MyHashtable.HashtableDebugView))> _
Class MyHashtable
Inherits Hashtable
Private Const TestString As String = "This should not appear in the debug window."
Friend Class HashtableDebugView
Private hashtable As Hashtable
Public Shared TestString As String = "This should appear in the debug window."
Public Sub New(ByVal hashtable As Hashtable)
Me.hashtable = hashtable
End Sub
<DebuggerBrowsable(DebuggerBrowsableState.RootHidden)> _
ReadOnly Property Keys as KeyValuePairs()
Get
Dim nkeys(hashtable.Count - 1) As KeyValuePairs
Dim i as Integer = 0
For Each key As Object In hashtable.Keys
nkeys(i) = New KeyValuePairs(hashtable, key, hashtable(key))
i = i + 1
Next
Return nkeys
End Get
End Property
End Class
End Class