告訴調試程式使用 DebuggerDisplay 屬性顯示的內容(C#、Visual Basic、F#、C++/CLI)
DebuggerDisplayAttribute 控制物件、屬性或字段在調試程式變數視窗中的顯示方式。 這個屬性可以套用至類型(類別、結構、列舉、委派),但通常只會套用至類別和結構。 如果套用至基底類型,屬性也會套用至子類別。
DebuggerDisplay
屬性有一個引數,即要顯示在型別實例的數值欄中的字串。 此字串可以包含大括號 ({
和 }
)。 大括號內的文字會被評估為欄位、屬性或方法。
如果類別具有覆寫 ToString()
方法,調試程式會使用覆寫的方法,而不是預設 {<typeName>}
。 因此,如果您已覆寫 ToString()
方法,調試程式會使用覆寫的方法,而不是預設 {<typeName>}
,而不需要使用 DebuggerDisplay
。 如果您同時使用兩者,則 DebuggerDisplay
屬性將優先於被覆寫的 ToString()
方法。
DebuggerDisplay
屬性優先於在子類別中覆寫的 ToString()
方法。
調試程式是否評估這個隱含 ToString()
呼叫,取決於 [工具/選項/偵錯] 對話框中的用戶設定。
重要
如果在 [工具/選項/偵錯] 對話框中選取 [在變數視窗 顯示物件的原始結構] 複選框,則會忽略 DebuggerDisplay
屬性。
注意
針對本機程式碼,此屬性僅支援 C++/CLI 程式碼。
下表顯示 DebuggerDisplay
屬性和範例輸出的一些可能用法。
屬性 | 在值欄中顯示的輸出 |
---|---|
[DebuggerDisplay("x = {x} y = {y}")] 在具有欄位 x 和 y 的類型上使用。 |
x = 5 y = 18 |
[DebuggerDisplay("String value is {getString()}")] 參數語法可能會因語言而異。 因此,請小心使用。 |
String value is [5, 6, 6] |
DebuggerDisplay
也可以接受具名參數。
參數 | 目的 |
---|---|
Name 、Type |
這些參數會影響變數視窗的 Name 和 Type 資料行。 (它們可以使用與建構函式相同的語法來設定為字串。過度使用這些參數或錯誤地使用這些參數可能會導致造成混淆的輸出。 |
Target 、TargetTypeName |
指定在元件層級使用 屬性時的目標類型。 |
autoexp.cs檔案會使用元件層級的DebuggerDisplay屬性。 autoexp.cs檔案會決定 Visual Studio 用於 .NET 物件的預設展開。 您可以檢查autoexp.cs檔案,以取得如何使用DebuggerDisplay屬性的範例,或者您可以修改和編譯autoexp.cs檔案來變更默認擴充。 請務必先備份autoexp.cs檔案,再加以修改。
若要建置autoexp.cs,請開啟 VS2015 的開發人員命令提示字元,然後執行下列命令
cd <directory containing autoexp.cs>
csc /t:library autoexp.cs
下一次除錯會話將會應用 autoexp.dll 的變更。
在「DebuggerDisplay」中使用運算式
雖然您可以在 DebuggerDisplay 屬性中的大括弧之間使用一般表達式,但不建議使用這種做法。
DebuggerDisplay 中的一般的程式運算式僅能隱式存取目前目標型別實例的 this
指標。 表達式無法存取別名、局部變數或指標。 如果表達式參考屬性,則不會處理這些屬性上的屬性。 例如,如果欄位 count
為 8,則 C# 程式代碼 [DebuggerDisplay("Object {count - 2}")]
會顯示 Object 6
。
在 DebuggerDisplay 中使用表示式可能會導致下列問題:
評估表達式是調試程式中成本最高的作業,而且每次顯示表達式時都會進行評估。 這可能會導致逐步執行程式碼時發生效能問題。 例如,當元素數目很大時,用來顯示集合或清單中的值的複雜表達式可能會非常慢。
表達式是由目前堆疊框架語言的表達式評估工具所評估,而不是由撰寫運算式之語言的評估工具所評估。 當語言不同時,這可能會導致無法預期的結果。
評估表達式可以變更應用程式的狀態。 例如,設定屬性值的表示式會改變執行程式碼中的屬性值。
減少表達式評估可能問題的方法之一,就是建立執行作業並傳回字串的私用屬性。 然後,DebuggerDisplay 特性可以顯示該私有屬性的值。 下列範例會實作此模式:
[DebuggerDisplay("{DebuggerDisplay,nq}")]
public sealed class MyClass
{
public int count { get; set; }
public bool flag { get; set; }
private string DebuggerDisplay
{
get
{
return string.Format("Object {0}", count - 2);
}
}
}
“,nq” 後綴會告訴表達式評估工具在顯示最終值時移除引號 (nq = 無引號)。
例
下列程式代碼範例示範如何使用 DebuggerDisplay
,以及 DebuggerBrowsable
和 DebuggerTypeProxy
。 在調試程式變數視窗中檢視時,例如 [監看] 視窗,它會產生如下所示的展開:
名稱 | 值 | 類型 |
---|---|---|
鑰匙 | “three” | 物件 {string} |
價值 | 3 | 物件 {int} |
[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("{DebuggerDisplay,nq}")]
[DebuggerTypeProxy(typeof(HashtableDebugView))]
class MyHashtable
{
public Hashtable hashtable;
public MyHashtable()
{
hashtable = new Hashtable();
}
private string DebuggerDisplay { get { return "Count = " + hashtable.Count; } }
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;
}
}
}
}
相關內容
- 使用 DebuggerTypeProxy 屬性
- 建立管理物件的自訂檢視
- C# 中的 格式規範
- 使用調試程序顯示屬性來增強偵錯