Почему Visual Studio Debugger не перечисляет BitArray и не показывает мне результаты? - PullRequest
12 голосов
/ 05 апреля 2011

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

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

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

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

РАЗЪЯСНЕНИЕ: Я спрашиваю, что происходит внутри оценщика выражений VS Debugger, а НЕ спрашиваю, как просмотреть BitArray в отладчике ..

1 Ответ

15 голосов
/ 05 апреля 2011

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

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

...