使用偵錯工具顯示屬性增強偵錯功能

更新:2007 年 11 月

偵錯工具顯示屬性可讓型別的開發人員 (也就是指定該型別的執行階段行為,而同時也最了解這個行為的人) 也能夠指定當該型別顯示在偵錯工具中時的面貌為何。此外,提供 Target 屬性的偵錯工具顯示屬性可以由使用者在組件層級套用,而不需要了解原始程式碼。DebuggerDisplayAttribute 屬性可控制型別或成員如何顯示在偵錯工具變數視窗中。DebuggerBrowsableAttribute 屬性可決定欄位或屬性是否會顯示在偵錯工具變數視窗中,以及其顯示的方式。DebuggerTypeProxyAttribute 屬性可為型別指定替代型別或 Proxy,以及變更該型別顯示在偵錯工具視窗中的方式。當您檢視有 Proxy 或替代型別的變數時,此 Proxy 表示偵錯工具顯示視窗中的原始型別。偵錯工具變數視窗只會顯示 proxy 型別的 Public 成員。不會顯示 Private 成員。

使用 DebuggerDisplayAttribute

DebuggerDisplayAttribute 建構函式有單一個引數:要顯示在型別執行個體之值欄中的字串,這個字串包含括號 ({ 和 })。一對括號中的文字會評估為運算式;例如,下列 C# 程式碼在選取加號 (+) 來展開 MyHashtable 執行個體的偵錯工具顯示時,會顯示 "Count = 4"。

[DebuggerDisplay("Count = {count}")]
class MyHashtable
{
    public int count = 4;
}

套用到此運算式中參考之屬性 (Property) 的屬性 (Attribute) 不會予以處理。對於 C# 編譯器而言,允許使用一般運算式 (此運算式對於目標型別的目前執行個體,只會有這個參考的隱含存取權)。此運算式有受到限制;無法存取別名、區域變數或指標。在 C# 程式碼中,您可以使用括號之間的一般運算式,此運算式只能對目標型別的目前執行個體之 this 指標有隱含存取權。

例如,如果 C# 物件有被覆寫的 ToString(),偵錯工具將會呼叫此覆寫,並顯示其結果,而不是標準 {<typeName>}.;因此,如果有被覆寫的 ToString(),則不需要使用 DebuggerDisplayAttribute。如果兩者都使用,DebuggerDisplayAttribute 屬性則會優先於 ToString() 覆寫。

使用 DebuggerBrowsableAttribute

DebuggerBrowsableAttribute 套用到欄位或屬性,以指定此欄位或屬性要如何顯示在偵錯工具視窗中。此屬性的建構函式會接受其中一個 DebuggerBrowsableState 列舉值,這個值可指定下列其中一個狀態:

  • Never 表示此成員不會顯示在資料視窗中。例如,在欄位上對 DebuggerBrowsableAttribute 使用這個值將會從階層架構中移除此欄位;當您在型別執行個體上按一下加號 (+) 來展開封入型別時,不會顯示此欄位。

  • Collapsed 表示預設情況下會顯示此成員,但是不會展開。這是預設行為。

  • RootHidden 表示不會顯示成員本身,但如果它是陣列或集合,則會顯示它的構成物件。

注意事項:

在 .NET Framework 2.0 版中,Visual Basic 不支援 DebuggerBrowsableAttribute

下列程式碼範例將顯示 DebuggerBrowsableAttribute 的用法,以防止其跟隨的屬性出現在類別的偵錯視窗中。

[DebuggerBrowsable(DebuggerBrowsableState.Never)]
public static string y = "Test String";

使用 DebuggerTypeProxy

當您需要大規模地從根本變更某型別的偵錯檢視,但不要變更該型別本身時,請使用 DebuggerTypeProxyAttribute 屬性。DebuggerTypeProxyAttribute 屬性是用來指定型別的顯示 Proxy,讓開發人員可以修改此型別的檢視。這個屬性就像 DebuggerDisplayAttribute 一樣,可以在組件層級使用,此時 Target 屬性會指定 Proxy 將使用的型別。建議的用法是讓這個屬性指定此型別內發生的私用巢狀型別 (這個屬性將會套用到此型別)。支援型別檢視器的運算式評估工具會在顯示型別時,檢查是否有這個屬性。如果有找到這個屬性,運算式評估工具會將顯示 Proxy 型別替代為套用此屬性的型別。

當有 DebuggerTypeProxyAttribute 存在時,偵錯工具變數視窗只會顯示 Proxy 型別的公用成員。不會顯示私用成員。有屬性增強的檢視不會變更資料視窗的行為。

為了避免不必要的效能負面影響,顯示 Proxy 的屬性要等到展開物件之後,才會予以處理,其處理方式是由使用者按一下資料視窗內型別旁邊的加號 (+),或是套用 DebuggerBrowsableAttribute 屬性。因此,建議您不要將任何屬性套用到顯示型別上,屬性可以且應該套用到顯示型別的主體中。

下列程式碼範例將示範 DebuggerTypeProxyAttribute 的用法,以指定要當做偵錯工具顯示 Proxy 使用的型別。

[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 2005 中檢視,以查看套用 DebuggerDisplayAttributeDebuggerBrowsableAttributeDebuggerTypeProxyAttribute 屬性的結果。

程式碼

Imports System
Imports System.Collections
Imports System.Diagnostics
Imports System.Reflection



Class DebugViewTest

    Shared Sub Main(ByVal args() As String) 
        Dim myHashTable As New MyHashtable()
        myHashTable.Add("one", 1)
        myHashTable.Add("two", 2)
        Console.WriteLine(myHashTable.ToString())
        Console.WriteLine("In Main.")

    End Sub 'Main 
End Class 'DebugViewTest
<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 'New
End Class 'KeyValuePairs
<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 Const TestString As String = "This should appear in the debug window."

        Public Sub New(ByVal hashtable As Hashtable)
            Me.hashtable = hashtable

        End Sub 'New
    End Class 'HashtableDebugView 
End Class 'MyHashtable
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(string[] args)
    {
        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;
         }
      }
   }
}

請參閱

參考

DebuggerDisplayAttribute

DebuggerBrowsableAttribute

DebuggerTypeProxyAttribute