在观察窗口中显示seq

时间:2010-08-18 12:54:14

标签: visual-studio debugging f#

有没有办法让Visual Studio调试器显示F#seq表达式的内容?

Visual Studio了解IEnumerable<T>个对象,并在监视窗口内为您提供结果视图。如果你在观察窗口中看到其中一个,你会得到一堆私人田地。

一些潜在的替代方案:

  • fsi.exe 可以很好地打印序列,但不会与调试器交互
  • 找到一种从调试器内部调用Seq.toArray的方法。我找不到正确的语法来调用,例如,立即窗口。
  • 写一个vizualiser。我不知道是否可以将vizualisers附加到Microsoft类型。
  • 别的什么......?

修改:进一步调查显示F#的seq个对象实现IEnumerable<T>就好了 - 它们会出现在观察窗口中 - 但由于某种原因,结果视图没有出现。

但是,F#seq对象似乎不是简单的IEnumerables;相反,它们看起来是来自Seq模块内部函数的闭包。(F#seq对象看起来是使用{ new IEnumerable with ... }创建的实例。)

4 个答案:

答案 0 :(得分:8)

执行此操作的一种方法是使用在Visual Studio 2008中添加的Results视图节点。如果将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>

答案 1 :(得分:3)

测试环境:

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 :(得分:2)

您可以通过将seq放入列表来强制进行评估。假设qseq<int>,这可以在观察窗口中使用:

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

BTW: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>

答案 3 :(得分:2)

那么,它们出现为闭包的原因是因为它们就是这样:seq直到你在代码中实际使用它们才被评估。你可以有一个无限的seq,这需要很长时间才能在调试器中显示。并且由于评估具有一些副作用并非不可能,因此对它们进行正确评估可能会导致仅在调试器或实际代码中显示但不在两者中都显示的问题。

如果您知道评估它没有问题,您可以将其放入列表或其他非惰性评估的集合中,然后检查它是否正确。