使用 DebuggerBrowsable 特性可以设置调式运行时属性在Watch窗口中的可视状态。
DebuggerBrowsable 使用 DebuggerBrowsableState 枚举来初始化,它有三个值:
- Collapsed 默认行为,显示元素
- Never 不在Debug窗口中显示元素
- RootHidden 隐藏父元素,直接显示子元素

Code
class Person
{
private string _lastName = string.Empty;
private string _firstName = string.Empty;
private int _age = 0;
private List<Person> _children = new List<Person>();
private List<string> _pets = new List<string>();
private List<string> _cars = new List<string>();
public string LastName
{
get { return _lastName; }
set { _lastName = value; }
}
public string FirstName
{
get { return _firstName; }
set { _firstName = value; }
}
public int Age
{
get { return _age; }
set { _age = value; }
}
[DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
public List<Person> Children
{
get{return _children;}
}
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
public List<string> Pets
{
get { return _pets; }
}
[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
public List<string> Cars
{
get { return _cars; }
}
public Person()
{
}
public Person(string lastName, string firstName, int age)
{
_lastName = lastName;
_firstName = firstName;
_age = age;
}
}
通过Type Proxy简化对象查看
使用 [DebuggerTypeProxy(typeof(XXXProxy))] 特性标记要简化查看的类,XXXProxy 是新创建的类,目的只是为了定义要在Watch窗口显示的属性

Code
internal class PersonProxy
{
private Person _person;
public PersonProxy(Person person)
{
_person = person;
}
public string Children
{
get
{
string[] children = new string[_person.Children.Count];
for(int i = 0; i<_person.Children.Count;i++)
{
children[i] = _person.Children[i].FirstName;
}
return string.Join(", ",children);
}
}
public string Pets
{
get { return string.Join(", ", _person.Pets.ToArray()); }
}
public string Cars
{
get { return string.Join(", ", _person.Cars.ToArray()); }
}
public string Person
{
get
{
return "Name = " + _person.FirstName + " " + _person.LastName +
", Age = " + _person.Age;
}
}
}
显示直观的Watch值

Code
[DebuggerDisplay("{_person.Age >= 21 ? \"Old Enough\" : \"Too Young\"}",
Type = "Alcohol Age Check")]
public string AlcoholAgeCheck
{
get { return string.Empty; }
}
如上代码,可以通过 DebuggerDisplay 特性使用条件判断来自定义Watch窗口显示的信息
如果单个三元运算不能满足,可以将判断代码封装到一个方法中去,如:

Code
private string ValidateObject()
{
List<string> violations = new List<string>();
//make sure that a first name has been specified
if (0 == _person.FirstName.Length)
{
violations.Add("FirstName is empty");
}
//make sure that a last name has been specified
if (0 == _person.LastName.Length)
{
violations.Add("LastName is empty");
}
//make sure that age is greater than 0
if (0 > _person.Age)
{
violations.Add("Age is less than 0");
}
//put additional validations here
//return results to DebuggerDisplay attribute
return string.Join(", ", violations.ToArray());
}
[DebuggerDisplay("{ValidateObject()}")]
public string BusinessRulesViolations
{
get { return string.Empty; }
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现