12

For the following line of C# code:

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

If I evaluate "bitty" in the Watch window, I don't see the members of the collection. If I evaluate "bitty, results", which is supposed to enumerate the IEnumerable and show the results, I get the message "Only Enumerable types can have Results View", even though a BitArray IS an IEnumerable.

Why does the debugger do this?

CLARIFICAITON: I'm asking what is happening inside the VS Debugger Expression Evaluator, NOT asking how to view a BitArray in the debugger..

Omer Raviv
  • 11,409
  • 5
  • 43
  • 82

1 Answers1

15

The results view only works for collections which meet the following conditions:

  1. Implement IEnumerable<T> or IEnumerable (VB.Net only works for IEnumerable<T>)
  2. Do not implement IList, IList<T>, ICollection or ICollection<T> (C# restriction only)
  3. Do not have a DebuggerTypeProxy attribute
  4. System.Core.dll is loaded in the debugee process

In this case BitArray implements both IEnumerable and ICollection. The latter disqualifies it from being used with the results view.

One way to work around this is to use the Cast extension method. This produces an IEnumerable<T> value from which you can use the results view

bitty.Cast<bool>(), results

The reason for #2 is a combination of factors:

  • The Results view was originally invented to solve a very specific problem: the debugging experience of C# iterators (and by extension LINQ queries) was poor. There was simply no good way to view the contents of the IEnumerable<T>.
  • The Results view is not free and does have very specific risks. In particular it will eagerly and synchronously load the entire collection into memory. This can cause issues with collections backed by database queries, extremely large or infinite collections
  • Every known IList/<T> and ICollection<T> type already have a method that let you view the contents

Hence the C# team decided to minimize risk and not add IEnumerable<T> to types which they felt already displayed well. VB.Net chose the other direction and will display it for any 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.

rmtheis
  • 5,992
  • 12
  • 61
  • 78
JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
  • @Jared: Now that's interesting. I was hovering around the idea that not applying the `DebuggerTypeProxyAttribute` kept it from showing up. I've noticed that other collections (generic and non-generic) applying this but not all. This would explain it though I wonder if this is actually documented somewhere. – Jeff Mercado Apr 04 '11 at 21:46
  • @Jeff it's not documented unfortunately and the VB and C# debuggers have different rules (in different versions of Visual Studio no less) on when the Results view will get displayed. I should probably write it down somewhere ... – JaredPar Apr 04 '11 at 21:47
  • @JaredPar Thanks for the answer! There is a 3rd condition that I think you missed - if a the value's concrete type is decorated with DebuggerTypeProxy, even if it doesn't qualify the two conditions you mentioned, it still won't get a Results View. Do you know by any chance the reason behind that 2nd rule? Are there versions of Visual Studio in which the ICollection/IList/ICollection/IList WILL be iterated and shown? – Omer Raviv Apr 04 '11 at 22:08
  • @Omer, forgot that (and one other requirement). Added both to my answer. I'll also add some information on why we didn't add them for `IList` and the like – JaredPar Apr 04 '11 at 22:11
  • LINQ to SQL's `EntitySet` seemed to have slipped through the cracks. It doesn't qualify for a 'Results View' and its debugger view doesn't display the items in it ([see here](http://stackoverflow.com/q/4490251)). – Allon Guralnek Jun 11 '11 at 08:49