【笔记】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封装的自定义控件资源库

相关推荐
wdfk_prog1 小时前
[Linux]学习笔记系列 -- [drivers][dma]dmapool
linux·笔记·学习
玄〤1 小时前
Java 大数据量输入输出优化方案详解:从 Scanner 到手写快读(含漫画解析)
java·开发语言·笔记·算法
2501_936960363 小时前
1.树莓派零基础教学
笔记
lzhdim3 小时前
C#开发的提示显示例子 - 开源研究系列文章
开发语言·c#
人工智能AI技术3 小时前
【C#程序员入门AI】向量数据库入门:C#集成Chroma/Pinecone,实现AI知识库检索(RAG基础)
人工智能·c#
呱呱巨基3 小时前
c语言 文件操作
c语言·开发语言·c++·笔记·学习
xb11323 小时前
C# 定时器和后台任务
开发语言·c#
hnult5 小时前
全功能学练考证在线考试平台,赋能技能认证
大数据·人工智能·笔记·课程设计
yangzheui5 小时前
【VUE2转VUE3学习笔记】-Day1:模板语法
vue.js·笔记·学习
Hammer_Hans5 小时前
DFT笔记27
笔记