2010-08-18 47 views
5

Có cách nào để gỡ lỗi Visual Studio để hiển thị nội dung của biểu thức F # seq không?Hiển thị một seq trong cửa sổ đồng hồ

Visual Studio biết về các đối tượng IEnumerable<T> và cung cấp cho bạn chế độ xem kết quả bên trong cửa sổ xem. Nếu bạn nhìn vào một trong những điều này trong cửa sổ xem, bạn sẽ nhận được một mớ hỗn độn của các trường riêng.

Một số lựa chọn thay thế tiềm năng:

  • fsi.exe làm một công việc tốt đẹp của chuỗi in ấn, nhưng nó không tương tác với các chương trình gỡ rối
  • Tìm một cách để gọi Seq.toArray từ bên trong trình gỡ lỗi. Tôi không thể tìm thấy cú pháp đúng để gọi điều này từ cửa sổ ngay lập tức.
  • Viết vizualiser. Tôi không biết nếu nó có thể đính kèm vizualisers cho các loại Microsoft.
  • Cái gì khác ...?

Edit: Tiếp tục điều tra tiết lộ rằng 's F # seq đối tượng thực hiện IEnumerable<T> tốt - chúng xuất hiện trong cửa sổ xem như vậy - nhưng vì một lý do xem kết quả không xuất hiện.

Tuy nhiên, F # seq các đối tượng dường như không đồng đều với IEnumerables; thay vào đó, họ xem là đóng cửa đến từ các hàm bên trong mô-đun Seq. (F # seq đối tượng được xem là trường hợp được tạo bằng cách sử dụng { new IEnumerable with ... }.)

+0

quá xấu LINQ không được hỗ trợ trong cửa sổ trình gỡ lỗi: http://blogs.msdn.com/b/jaredpar/archive/2009/08/26/why-no-linq-in-debugger-windows. aspx –

+0

xem câu trả lời của tôi về cách để có được nút Kết quả xuất hiện – JaredPar

Trả lời

8

Một cách để làm điều này là sử dụng nút Results xem mà đã được bổ sung trong Visual Studio 2008. Nếu tính năng System. Core.dll được nạp vào quá trình, bất kỳ loại nào thực hiện IEnumerable<T> sẽ nhận được một nút bổ sung khi mở rộng có tên là Results. Việc mở rộng nút đó sẽ liệt kê các số IEnumerable<T> và hiển thị kết quả.

Loại F # seq chỉ là bí danh cho IEnumerable<T> để nó có cùng lợi ích.

results view

Theo mặc định bạn không thấy điều này trong F # vì nó không sử dụng bất kỳ loại trong System.Core. Nhưng bạn có thể buộc DLL này vào quá trình wit dòng sau.

// Force System.Core into the process 
let x = typeof<System.Linq.Enumerable> 
+0

Chỉ vì tò mò, điều gì xảy ra khi một IEnumerable là một danh sách vô hạn? – Gabe

+2

Thật tuyệt vời. Bạn không cần sửa đổi mã của mình. Nó hoạt động nếu bạn gõ vào cửa sổ ngay lập tức: 'System.Reflection.Assembly.Load (" System.Core, Version = 3.5.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089, processorArchitecture = MSIL ")' –

+0

@Gabe, At điểm đó mở rộng khung nhìn Result về cơ bản sẽ treo cho đến khi cuộc gọi đến trình gỡ rối hết thời gian (giả sử IEnumerable là 100% mã được quản lý). Nếu nó là bản địa, bạn có thể kết thúc với một tràn Stack, bế tắc, hết bộ nhớ ... Đây là những lý do quan điểm kết quả không mở rộng nội tuyến theo mặc định. – JaredPar

2

Bạn có thể buộc đánh giá bằng cách đặt seq vào danh sách. Giả sử q là một seq<int>, công trình này trong cửa sổ xem:

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

BTW: seq một bí danh cho IEnumerable. Như được định nghĩa trong prim-types.fsi:

/// <summary>An abbreviation for the CLI type <c>System.Collections.Generic.IEnumerable&lt;_&gt;</c></summary> 
type seq<'T> = IEnumerable<'T> 
+0

Chi tiết, nhưng nó hoạt động! Cảm ơn. –

2

Vâng, lý do chúng xuất hiện dưới dạng đóng là vì chúng không được đánh giá cho đến khi bạn thực sự sử dụng chúng trong mã. Bạn có thể có một seq vô hạn, và sẽ mất khá nhiều thời gian để hiển thị trong trình gỡ rối. Và vì không thể đánh giá có một số tác dụng phụ, việc đánh giá chúng đúng một sáng tạo có thể gây ra vấn đề chỉ hiển thị trong trình gỡ lỗi hoặc trong mã thực nhưng không phải ở cả hai.

Nếu bạn biết rằng không có vấn đề gì với việc đánh giá nó, bạn có thể đặt nó vào danh sách hoặc bộ sưu tập khác không được đánh giá lười và sau đó kiểm tra xem nó có chính xác không.

+0

Nhưng một IEnumerable đơn giản, trong bất kỳ ngôn ngữ .NET nào khác, cũng rất lười. Đó là lý do tại sao, khi bạn có một chuỗi C#, Visual Studio làm cho bạn mở khung nhìn kết quả bằng tay. Tôi không chắc tại sao F # cần đóng cửa ở đây. –

+0

Vâng, nếu tôi đọc câu hỏi này một cách chính xác http://stackoverflow.com/questions/2049806/debugging-an-ienumerable-method, Lazy IEnumerable cũng không nên hiển thị. Tôi đoán tại thời điểm này là trình gỡ lỗi là đủ thông minh để phát hiện khi một IEnumerable không phải là lười biếng đánh giá (nếu nó là ví dụ một danh sách) và sau đó hiển thị nó trong trình gỡ lỗi. –

3

môi trường thử nghiệm:

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

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

này nên thực hiện công việc trong cửa sổ Quickwatch:

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

Hoặc bạn có thể thêm dòng này để đảm bảo rằng System.Core được nạp (và System.Linq.Đếm được có thể truy cập)

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

sau đó bạn có thể sử dụng cú pháp này trong QuickWatch

System.Linq.Enumerable.ToList(s) 
Các vấn đề liên quan