Почему 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 ответ
Представление результатов работает только для коллекций, которые удовлетворяют следующим условиям:
- Воплощать в жизнь
IEnumerable<T>
или жеIEnumerable
(VB.Net работает только дляIEnumerable<T>
) - Не осуществлять
IList
,IList<T>
,ICollection
или жеICollection<T>
(Только ограничение C#) - Не иметь
DebuggerTypeProxy
атрибут - 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
хотя и по вышеуказанным правилам.