为什么Visual Studio Debugger不会枚举BitArray并向我显示结果?
对于以下C#代码行:
BitArray bitty = new BitArray(new[] {false, false, true, false});
如果我在Watch窗口中评估“bitty”,我看不到集合的成员。 如果我评估“bitty,results”,它应该枚举IEnumerable并显示结果,我会收到消息“只有可枚举的类型可以有结果视图”,即使BitArray是一个IEnumerable。
为什么调试器会这样做?
CLARIFICAITON:我问的是VS Debugger Expression Evaluator中发生了什么,而不是询问如何在调试器中查看BitArray。
结果视图仅适用于满足以下条件的集合:
- 实现
IEnumerable
或IEnumerable
(VB.Net仅适用于IEnumerable
) - 不要实现
IList
,IList
,ICollection
或ICollection
(仅限C#限制) - 没有
DebuggerTypeProxy
属性 - 在debugee进程中加载System.Core.dll
在这种情况下, BitArray
实现IEnumerable
和ICollection
。 后者取消了它与结果视图一起使用的资格。
解决此问题的一种方法是使用Cast
扩展方法。 这将生成一个IEnumerable
值,您可以从中使用结果视图
bitty.Cast(), results
#2的原因是多种因素的组合:
- 结果视图最初是为解决一个非常具体的问题而发明的:C#迭代器(以及扩展LINQ查询)的调试体验很差。 没有好的方法来查看
IEnumerable
的内容。 - 结果视图不是免费的,并且确实存在非常具体的风险。 特别是它将热切地和同步地将整个集合加载到存储器中。 这可能会导致数据库查询,极大或无限集合支持的集合出现问题
- 每个已知的
IList/
和ICollection
类型都有一个允许您查看内容的方法
因此,C#团队决定将风险降至最低,而不是将IEnumerable
添加到他们认为已经很好地显示的类型中。 VB.Net选择了另一个方向,并将为任何IEnumerable
显示它。
您可能会理所当然地询问两个团队如何查看相同的数据并做出不同的决策。 它归结为视角和时间。 VB.Net团队非常热衷于提供出色的LINQ调试体验。 VB.Net在提供丰富的调试+ ENC经验方面有着悠久的历史,因此更习惯/愿意承担此类风险,并且还具有测试它的带宽。 C#只是更加厌恶风险,在时间表上非常紧张,并且务实地决定反对它。
注意:我之前对IEnumerable
不支持的困惑是因为VB表达式求值程序实际上就是这种情况。 C#表达式求值程序确实通过上述规则支持IEnumerable
。