使用 DebuggerDisplay 属性
更新:2007 年 11 月
本主题适用于:
版本 |
Visual Basic |
C# |
C++ |
Web Developer |
---|---|---|---|---|
速成版 |
||||
标准版 |
||||
专业团队版 |
表格图例:
适用 |
|
不适用 |
|
默认情况下隐藏的一条或多条命令。 |
DebuggerDisplay 属性 (System.Diagnostics.DebuggerDisplayAttribute) 控制类或字段在调试器变量窗口中的显示方式。此属性可应用于:
类
结构
委托
枚举
字段
属性
程序集
DebuggerDisplay 属性有一个参数,此参数是要在值列中显示的表示类型实例的字符串。此字符串可以包含大括号({ 和 })。一对大括号之间的文本将作为字段、属性或方法来计算。
在 C# 代码中,可以在大括号之间使用常规表达式。该表达式只能隐式访问目标类型当前实例的 this 指针,不能访问别名、局部变量或指针。如果表达式引用属性 (Property),则不处理这些属性 (Property) 上的属性 (Attribute)。
如果 C# 对象有重写的 ToString(),则调试器将调用该重写并显示重写的结果而不是标准 ToString()。因此,如果您已重写 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 文件之前一定要对它进行备份。必须引用 \Program Files\Microsoft Visual Studio 9.0\Common7\IDE\PublicAssemblies 中的 Microsoft.VisualStudio.DebuggerVisualizers.dll。可以在 My Documents/Visual Studio 9.0/Visualizers 中找到 autoexp.cs 文件。 |
示例
下面的代码示例演示如何使用 DebuggerDisplay 以及 DebuggerBrowseable 和 DebuggerTypeProxy。在调试器变量窗口(如“监视”窗口)中查看时,它生成类似以下内容的扩展:
名称 |
值 |
类型 |
---|---|---|
Key |
"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("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;
}
}
}
}