Показать последовательность в окне просмотра - PullRequest
5 голосов
/ 18 августа 2010

Есть ли способ заставить отладчик Visual Studio отображать содержимое выражения F # seq?

Visual Studio знает о IEnumerable<T> объектах и ​​дает вам представление результатов в окне просмотра.Если вы посмотрите на один из них в окне просмотра, вы получите кучу личных полей.

Некоторые потенциальные альтернативы:

  • fsi.exe делает хорошозадание печати последовательностей, но оно не взаимодействует с отладчиком
  • Найдите способ вызова Seq.toArray изнутри отладчика.Я не могу найти правильный синтаксис для вызова этого, скажем, из окна «Немедленное».
  • Написать визуализатор.Я не знаю, возможно ли присоединить визуализаторы к типам Microsoft.
  • Что-то еще ...?

Редактировать: Дальнейшие исследования показывают, что F # 's seq объекты реализуют IEnumerable<T> очень хорошо - они отображаются в окне просмотра как таковые - но по некоторым причинам представление результатов не появляется.

Однако объекты F # seq не имеютне кажется простым IEnumerables;вместо этого они выглядят как замыкания, поступающие от функций внутри модуля Seq. (объекты F # seq выглядят как экземпляры, созданные с использованием { new IEnumerable with ... }.)

Ответы [ 4 ]

8 голосов
/ 18 августа 2010

Один из способов сделать это - использовать узел представления Results, добавленный в Visual Studio 2008. Если в процесс загружен файл System.Core.dll, любой тип, который реализует IEnumerable<T>, получит дополнительный узел, расширенное имя Results. Расширение этого узла перечислит IEnumerable<T> и отобразит результаты.

Тип F # seq - это просто псевдоним для IEnumerable<T>, поэтому он получает то же преимущество.

results view

По умолчанию вы не видите этого в F #, потому что он не использует какие-либо типы в System.Core. Но вы можете принудительно включить эту DLL в процесс с помощью следующей строки.

// Force System.Core into the process
let x = typeof<System.Linq.Enumerable>
3 голосов
/ 18 августа 2010

Тестовая среда:

let get s = 
    for x in s do // breakpoint is set here
        printfn "%A" s

get <| seq {for i in 1..10 -> i}

Это должно сделать работу в окне Quickwatch:

Microsoft.FSharp.Collections.SeqModule.ToArray(s)

Или вы можете добавить эту строку, чтобы загрузить System.Core (и System.Linq.Enumerable доступен)

let s : System.Linq.Expressions.Expression = Unchecked.defaultof<_>

после этого вы можете использовать этот синтаксис в QuickWatch

System.Linq.Enumerable.ToList(s)
2 голосов
/ 18 августа 2010

Ну, причина, по которой они выглядят как замыкания, в том, что это то, чем они являются: seq не оценивается, пока вы фактически не используете их в коде.Вы можете иметь бесконечный seq, и это займет довольно много времени, чтобы показать в отладчике.И поскольку не исключено, что оценка имеет некоторый побочный эффект, правильная их оценка и создание могут вызвать проблемы, которые отображаются только в отладчике или в реальном коде, но не в обоих.

Если вы знаете, что нетпроблема с его оценкой, вы можете поместить его в список или другую коллекцию, которая не лениво оценивается, а затем проверить, является ли она правильной.

2 голосов
/ 18 августа 2010

Вы можете форсировать оценку, поместив последовательность в список. Предполагая, что q является seq<int>, это работает в окне просмотра:

new System.Collections.Generic.List<int>(q)

Кстати: seq - это псевдоним для IEnumerable. Как определено в prim-types.fsi:

/// <summary>An abbreviation for the CLI type <c>System.Collections.Generic.IEnumerable&lt;_&gt;</c></summary>
type seq<'T> = IEnumerable<'T>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...