原文链接:Visual Studio Tips - DebuggerDisplay

集合数据类型的监视问题

以 Person 类为例:

  1. public class Person
  2. {
  3. public string FirstName { get; set; }
  4. public string LastName { get; set; }
  5. }

当监视 List 时,常遇到的一个问题就是:在监控界面无法直观看到集合内每个 Person 实例的值。

image.png

除非你像下面这样再展开一次。但有时候要花很长时间才能找到目标值。

image.png

该问题最常见的处理方法是重写 Person 类的 ToString() 方法,然后在调试时将数据打印出来。

现在通过 DebuggerDisplay 我们可以更优雅的解决该问题。

DebuggerDisplay

官方文档:Tell the debugger what to show using the DebuggerDisplay Attribute
扩展阅读:DebuggerDisplay attribute best practices

修改 Person 类,添加 DebuggerDisplay 特性:

  1. public class Person
  2. {
  3. [DebuggerDisplay("{LastName,nq},{FirstName.Length >= 5 ? FirstName.Substring(0, 5) : FirstName, nq}")]
  4. public string FirstName { get; set; }
  5. public string LastName { get; set; }
  6. }

注:nq 表示调试输出时去掉字符串前后的引号。

效果:

image.png

DebuggerTypeProxy

除了 DebuggerDisplay,对于原始类型可以使用 DebuggerTypeProxy

下面以优化 byte[] 的监视为例(参考自 SOF)。

未优化前,必须展开才能看到数组内部的值:

image.png

创建针对 byte[] 的 Debug View:

  1. public class ByteArrayHexView
  2. {
  3. [DebuggerBrowsable(DebuggerBrowsableState.Never)]
  4. private byte[] array;
  5. public string Hex => String.Join(", ", array.Select(x => $"0x{x:X2}"));
  6. public ByteArrayHexView(byte[] array)
  7. {
  8. this.array = array;
  9. }
  10. }

通过 DebuggerTypeProxy 指定 byte[] 类型的 Debug View:

  1. [assembly: DebuggerTypeProxy(typeof(ByteArrayHexView), Target = typeof(byte[]))]
  2. namespace ConsoleTest
  3. {
  4. static class Program
  5. {
  6. static void Main()
  7. {
  8. var bytes = new byte[] {0x01, 0x02, 0x03};
  9. }
  10. }
  11. }

优化后的效果:

image.png

注:最完美的效果应该是直接在 {byte[3]} 那个位置显式 Hex,但折腾了一阵暂时没找到方法。