12

对于以下 C# 代码行:

BitArray bitty = new BitArray(new[] {false, false, true, false});

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

为什么调试器会这样做?

澄清:我问的是 VS 调试器表达式评估器内部发生了什么,而不是问如何在调试器中查看 BitArray ..

4

1 回答 1

15

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

  1. 实现IEnumerable<T>IEnumerable (VB.Net 仅适用于IEnumerable<T>
  2. 不要实现,IList , or IList<T>(仅限 C# 限制)ICollectionICollection<T>
  3. 没有属性_ _DebuggerTypeProxy
  4. System.Core.dll 在被调试进程中加载

在这种情况下BitArray,同时实现IEnumerableICollection。后者使其无法与结果视图一起使用。

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

bitty.Cast<bool>(), results

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

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

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

You might rightfully ask how two teams could look at the same data and make different decisions. It comes down to perspective and of course time. The VB.Net team was very keen on providing a great LINQ debugging experience. VB.Net has a long history of providing a rich debugging + ENC experience and hence was more accustomed / willing to take this type of risk on and additionally had the bandwidth to test it. C# was simply more risk averse, very tight on the schedule and pragmatically decided against it.

Note: My earlier confusion about IEnumerable not being supported is because that's actually the case in the VB expression evaluator. The C# expression evaluator does support IEnumerable though and by the above rules.

于 2011-04-04T21:01:20.753 回答