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

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

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

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

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

Уточнение: я спрашиваю, что происходит внутри VS Debugger Expression Evaluator, а не спрашиваю, как просмотреть BitArray в отладчике.

1 ответ

Решение

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

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

В этом случае 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 хотя и по вышеуказанным правилам.

Другие вопросы по тегам