2011-04-05 50 views
4

這是我經常希望能夠在調試時做的事情。如果我有一個行代碼計算foreach循環的水箱內的集合:是否有可能在調試時「看到」C#foreach循環的迭代集合?

foreach (var item in someObject.GetItems(someParameter)) { 
    ... 
} 

似乎沒有要什麼我可以將鼠標懸停在獲得計算出的設定由GetItems返回的項目,甚至儘管它被清楚地計算並返回以便循環能夠執行。

只是看起來很明顯會很方便。我錯過了什麼嗎?重寫代碼以將列表存儲在變量中僅僅是是一件很痛苦的事情,所以我可以在調試時看到它,特別是當我發現一個不容易重現的錯誤時。

+0

這裏有兩個不同的問題: (a)在調試器中看到被迭代的對象,就像人們可以看到本地或對象級別變量的值一樣()(b)提取一個惰性集合的內容在調試期間。 我認爲(a)是你正在試圖解決的問題嗎? – Stewart 2017-05-23 10:54:46

回答

3

一種方法是隻需添加下面的表達式來監視窗口

someObject.GetItems(someParameter); 

懸停不會爲這種情況下工作,但它明確地增加了觀察窗口會。在懸停時評估表達式而不評估函數的代碼中有很多注意事項。邏輯是功能很昂貴,會導致IDE死鎖,我們不希望懸停操作導致死鎖。該表達式的GetItems部分是功能評估,因此EE拒絕評估它。

+0

謝謝,這是一個很好的解決方法,如果我需要檢查它而不重新啓動。沒有想到這一點。 – devios1 2011-04-05 16:07:33

+0

爲什麼懸停在表達式上必須再次評估它?毫無疑問,如果MS進行這項工作,這將是一個顯示已經評估過的值的問題。這將避免再次評估表達式的開銷和潛在副作用。 當然,如果每當foreach循環正在進行時,在Locals窗口中顯示的評估值會更好。 – Stewart 2017-05-23 10:58:56

9

一種選擇是在循環之前將它分配給一個臨時變量。

var items = someObject.GetItems(someParameter); 
foreach (var item in items) { 
    ... 
} 

這將允許您直接檢查items

即使它被明確計算並返回以便循環能夠執行。

問題是,這是不正確的。

如果GetItemsIEnumerableIEnumerable<T>,它可能不會被評估。實際上,「收集」可以是無限的枚舉。

+0

+1爲「無限枚舉」 – 2011-04-05 16:30:22

+0

雖然這當然是真的,但我不認爲它是一個解決方案,因爲我的問題是具體如何避免這樣做。感謝壽。 – devios1 2011-04-05 22:12:34

+0

@chaiguy:我試圖告訴你爲什麼沒有直接的方式 - 手錶可以在某些情況下工作,但在其他情況下可能有潛在危險(因爲枚舉可能有副作用)。 – 2011-04-05 22:39:06

1

不幸的是Visual Studio調試器沒有這個功能。

請注意,在一般情況下,它不能。該集合可能是一個複雜計算的迭代器塊;你不希望調試器比程序更頻繁地評估它。

當然但還有明顯的解決方法,以收集存儲在一個變量:

var items = someObject.GetItems(someParameter); 
foreach (var item in items) { 
    ... 
} 

現在你可以看看items在調試器。當然也有相同的限制 - 如果它是一個複雜的枚舉類型,調試器將不會顯示一個方便的項目列表。但在常見的情況下(例如列表,數組等),它的確如此。

相關問題