【笔记】DebuggerDisplay、DebuggerBrowsable 及其相关“系列”特性的系统性说明

下面是对 DebuggerDisplay、DebuggerBrowsable 及其相关"系列"特性的系统性说明,涵盖概念、语法、选项、示例、性能与调试器行为等。

一、DebuggerDisplay

  • 作用:自定义对象在调试器中的显示文本(Locals/Watch/数据提示)。
  • 用法:在类型或成员上标注 [DebuggerDisplay("格式字符串")]
  • 格式字符串语法:
    • 文本常量:"MyType"
    • 引用成员:{Member},支持属性、字段、无参实例方法,如 {Id}{Count}{GetState()}
    • 去引号:{Name,nq} 对字符串去除引号
    • 可组合:"Id={Id}, Count={Items.Count}, Ready={IsReady}"
  • 注意事项:
    • 求值发生在调试暂停时,若成员访问抛异常,调试器显示错误提示。
    • 避免昂贵或有副作用的 getter/方法。
  • 示例(通用):
csharp 复制代码
using System.Diagnostics;

[DebuggerDisplay("{Name,nq} (Id={Id}, Count={Items.Count})")]
public class Sample
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<int> Items { get; } = new List<int>();
  }

二、DebuggerBrowsable

  • 作用:控制成员在调试器中的可见性与展开方式,减少噪声或提供更友好的展开视图。
  • 用法:标注在字段或属性上(常用于字段)。
  • 枚举值:
    • DebuggerBrowsableState.Never:在调试器中隐藏该成员。
    • DebuggerBrowsableState.RootHidden:将该成员的元素直接作为父对象的子级展开显示(典型用于集合字段/属性)。
    • DebuggerBrowsableState.Collapsed:成员在调试器中默认折叠(具体效果依调试器版本而定,常见实现可能忽略)。
  • 示例(隐藏或扁平化集合):
csharp 复制代码
using System.Diagnostics;

public class Bag<T>
{
    [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
    public T[] Items;

    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    private string _debugNoise; // 在调试器中不显示
  }
  • 注意事项:
    • RootHidden 适用于返回数组或实现 IEnumerable 的成员;展开时元素直接显示,父级容器成员名不出现。
    • 对属性使用时需留意 getter 是否有副作用。

三、DebuggerTypeProxy(同属"调试视图系列",常与以上配合)

  • 作用:为类型提供一个"调试专用代理视图",在调试器中以代理的公开成员来展示对象,适合复杂对象/集合。
  • 用法:在类型上标注 [DebuggerTypeProxy(typeof(MyTypeDebugView))]
  • 示例(为集合自定义可读视图):
csharp 复制代码
using System.Diagnostics;
using System.Linq;

[DebuggerTypeProxy(typeof(InventoryDebugView))]
public class Inventory
{
    public List<Item> Items { get; } = new List<Item>();
    public string Name { get; set; }
}

internal sealed class InventoryDebugView
{
    private readonly Inventory _inv;
    public InventoryDebugView(Inventory inv) => _inv = inv;

    // 在调试器中以数组展开
    public object[] Items => _inv.Items
        .Select(i => new { i.Id, i.Title, i.Stock })
          .ToArray();
  }
  • 注意事项:
    • 代理仅在调试器中使用,不参与运行。
    • 代理成员应轻量、无副作用,避免 IO/锁/昂贵计算。

四、DebuggerStepThrough / DebuggerNonUserCode / DebuggerHidden(相关调试行为特性)

  • DebuggerStepThrough:指示调试器在单步执行时跳过标注的代码(仍可设置断点)。
  • DebuggerNonUserCode:将代码标记为非用户代码,调试器默认不步入。
  • DebuggerHidden:隐藏方法,使调试器无法在此处设置断点或步入(慎用)。
  • 用途:控制单步体验,减少进入框架/样板代码。

五、组合最佳实践

  • DebuggerDisplay:展示关键、廉价、稳定的状态(Id、Name、Count、简单 Flags)。
  • DebuggerBrowsable:
    • 对"内部实现细节"使用 Never 隐藏,降低视觉噪声。
    • 对集合用 RootHidden 扁平化,便于直接查看元素。
  • DebuggerTypeProxy:为复杂对象/集合提供结构化视图(数组、投影),避免在 DebuggerDisplay 中塞过多信息。
  • 性能与安全:
    • 避免在调试视图中触发昂贵或有副作用操作(数据库、磁盘、网络、锁)。
    • Getter 内避免复杂副作用逻辑,防止调试卡顿。
    • 若遇到评估过于频繁导致性能问题,可调整 Visual Studio 设置:Tools > Options > Debugging > General,如关闭"Enable property evaluation and other implicit function calls"。

六、常见问题与规避

  • 成员名拼写错误导致显示为空或错误提示。
  • 在 DebuggerDisplay 中调用可能抛异常的方法,影响调试体验。
  • 使用 RootHidden 但返回类型不是可枚举/数组,导致视图不如预期。
  • 在代理视图或属性 getter 中执行昂贵逻辑引发卡顿或阻塞。

七、在 Visual Studio 中查看与验证

  • 暂停后在 Debug > Windows > LocalsWatch、悬停数据提示查看效果。
  • 如需精简自动求值,调整 Tools > Options > Debugging > General 的相关选项。
  • 若想只在调试器中显示某些成员,可以把它们放在代理视图中,原类型中使用 DebuggerBrowsable(Never) 隐藏实现字段。

了解更多

DebuggerDisplayAttribute Class

DebuggerBrowsableAttribute Class

DebuggerHiddenAttribute Class

DebuggerTypeProxyAttribute Class

System.Windows.Controls 命名空间 | Microsoft Learn

控件库 - WPF .NET Framework | Microsoft Learn

WPF 介绍 | Microsoft Learn

使用 Visual Studio 创建新应用教程 - WPF .NET | Microsoft Learn

https://github.com/HeBianGu

HeBianGu的个人空间-HeBianGu个人主页-哔哩哔哩视频

GitHub - HeBianGu/WPF-Control: WPF轻量控件和皮肤库

GitHub - HeBianGu/WPF-ControlBase: Wpf封装的自定义控件资源库

相关推荐
William Dawson5 小时前
2026软考中级系统集成项目管理工程师备考笔记
笔记·系统集成项目管理工程师
love530love7 小时前
精简版|Claude-HUD 插件介绍 + 一键安装教程
人工智能·windows·笔记
想成为优秀工程师的爸爸8 小时前
第三十篇技术笔记:郭大侠学UDS - 人有生老三千疾,望闻问切良方医
网络·笔记·网络协议·tcp/ip·信息与通信
tq10869 小时前
数学:约束表征空间的最小闭包
笔记
freexyn11 小时前
Matlab自学笔记七十六:表达式的展开、因式分解、化简、合并同类项
笔记·算法·matlab
IT摆渡者13 小时前
linux 系统安全检查
运维·网络·经验分享·笔记
宝桥南山13 小时前
GitHub Models - 尝试一下使用GitHub Models
microsoft·ai·微软·c#·github·.netcore
十安_数学好题速析14 小时前
【多选】曲线方程:四步避坑判断曲线类型
笔记·学习·高考
hixiong12316 小时前
C# OpenvinoSharp部署INSID3
开发语言·人工智能·ai·c#·openvinosharp
chase。16 小时前
【学习笔记】skrl: 模块化、灵活的强化学习库深度解析
笔记·学习