为什么Visual Studio Debugger不会枚举BitArray并向我显示结果?

Ome*_*viv 12 c# debugging visual-studio visual-studio-debugging

对于以下C#代码行:

BitArray bitty = new BitArray(new[] {false, false, true, false});
Run Code Online (Sandbox Code Playgroud)

如果我在Watch窗口中评估"bitty",我看不到集合的成员.如果我评估"bitty,results",它应该枚举IEnumerable并显示结果,我会收到消息"只有可枚举的类型可以有结果视图",即使BitArray是一个IEnumerable.

为什么调试器会这样做?

CLARIFICAITON:我问的是VS Debugger Expression Evaluator中发生了什么,而不是询问如何在调试器中查看BitArray.

Jar*_*Par 15

结果视图仅适用于满足以下条件的集合:

  1. 实现IEnumerable<T>IEnumerable (VB.Net仅适用于IEnumerable<T>)
  2. 不要落实IList,IList<T>,ICollection或者ICollection<T>(仅C#的限制)
  3. 千万不能DebuggerTypeProxy属性
  4. 在debugee进程中加载​​System.Core.dll

在这种情况下BitArray实现两个IEnumerableICollection.后者取消了它与结果视图一起使用的资格.

解决此问题的一种方法是使用Cast扩展方法.这将生成一个IEnumerable<T>值,您可以从中使用结果视图

bitty.Cast<bool>(), results
Run Code Online (Sandbox Code Playgroud)

#2的原因是多种因素的组合:

  • 结果视图最初是为解决一个非常具体的问题而发明的:C#迭代器(以及扩展LINQ查询)的调试体验很差.根本没有好办法查看内容IEnumerable<T>.
  • 结果视图不是免费的,并且确实存在非常具体的风险.特别是它将热切地和同步地将整个集合加载到存储器中.这可能会导致数据库查询,极大或无限集合支持的集合出现问题
  • 每个已知IList/<T>ICollection<T>类型已经有一个方法,让您查看内容

因此,C#团队决定将风险降至最低,而不是添加IEnumerable<T>他们认为已经很好地显示的类型.VB.Net选择了另一个方向,并将为任何方向显示它IEnumerable<T>.

您可能会理所当然地询问两个团队如何查看相同的数据并做出不同的决策.它归结为视角,当然还有时间.VB.Net团队非常热衷于提供出色的LINQ调试体验.VB.Net在提供丰富的调试+ ENC经验方面有着悠久的历史,因此更习惯/愿意承担此类风险,并且还具有测试它的带宽.C#只是更加厌恶风险,在时间表上非常紧张,并且务实地决定反对它.

注意:我之前对IEnumerable不受支持的困惑是因为VB表达式求值程序实际上就是这种情况.C#表达式求值程序确实支持IEnumerable并遵循上述规则.