Почему отладчик Visual Studio не перечисляет массив BitArray и не показывает результаты?

Для следующей строки кода C#:

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

Если я оцениваю «битти» в окне просмотра, я не вижу членов коллекции. Если я оцениваю «bitty, results», который должен перечислять IEnumerable и показывать результаты, я получаю сообщение «Только типы Enumerable могут иметь представление результатов», даже если BitArray ЯВЛЯЕТСЯ IEnumerable.

Почему отладчик делает это?

ПОЯСНЕНИЕ: я спрашиваю, что происходит внутри VS Debugger Expression Evaluator, а НЕ спрашиваю, как просмотреть BitArray в отладчике.


person Omer Raviv    schedule 04.04.2011    source источник


Ответы (1)


Просмотр результатов работает только для коллекций, отвечающих следующим условиям:

  1. Реализовать IEnumerable<T> или IEnumerable (VB.Net работает только для IEnumerable<T>)
  2. Не реализовывать IList, IList<T>, ICollection или ICollection<T> (только ограничение C#)
  3. У нет атрибута DebuggerTypeProxy
  4. System.Core.dll загружается в отлаживаемый процесс

В этом случае BitArray реализует как IEnumerable, так и ICollection. Последнее исключает его использование с представлением результатов.

Один из способов обойти это — использовать метод расширения Cast. Это создает значение IEnumerable<T>, из которого вы можете использовать представление результатов.

bitty.Cast<bool>(), results

Причиной № 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, хотя и в соответствии с приведенными выше правилами.

person JaredPar    schedule 04.04.2011
comment
@Jared: Вот это интересно. Я колебался вокруг идеи, что если не применить DebuggerTypeProxyAttribute, он не появится. Я заметил, что другие коллекции (универсальные и неуниверсальные) применяют это, но не все. Это объяснило бы это, хотя мне интересно, действительно ли это где-то задокументировано. - person Jeff Mercado; 05.04.2011
comment
@Jeff, к сожалению, это не задокументировано, и отладчики VB и C # имеют разные правила (не меньше в разных версиях Visual Studio) в отношении того, когда будет отображаться представление «Результаты». Наверное, надо куда-нибудь записать... - person JaredPar; 05.04.2011
comment
@JaredPar Спасибо за ответ! Есть третье условие, которое, я думаю, вы пропустили: если конкретный тип значения украшен DebuggerTypeProxy, даже если он не соответствует двум упомянутым вами условиям, он все равно не получит представление результатов. Вы случайно не знаете причину этого второго правила? Существуют ли версии Visual Studio, в которых ICollection/IList/ICollection‹T›/IList‹T› БУДЕТ повторяться и отображаться? - person Omer Raviv; 05.04.2011
comment
@ Омер, забыл об этом (и еще одно требование). Добавил оба в мой ответ. Я также добавлю информацию о том, почему мы не добавили их для IList и т.п. - person JaredPar; 05.04.2011
comment
LINQ to SQL EntitySet<T>, похоже, проскользнул сквозь трещины. Он не подходит для «Просмотра результатов», и его представление отладчика не отображает содержащиеся в нем элементы (см. здесь). - person Allon Guralnek; 11.06.2011