2017-07-27 53 views
2
var counter=0; 
var array = new int[] {0, 1, 2, 3,4}; 

var test = array.Select(a => counter++); 

foreach (var item in test) 
{ 
    Console.WriteLine(item); 
} 

Console.ReadLine(); 

當我在控制檯上方運行代碼時,會打印0,1,2,3,4。 但是,當我在調試模式下展開測試數組時,我可以看到數字從10到14.爲什麼? 另外,你能幫我一下爲什麼控制檯不打印1,2,3,4,5,因爲它應該返回遞增的計數器。C#Linq打印比在調試模式下顯示的值不同

DebugMode

+4

使用'array.Select(a => counter ++)。ToList()'它會停止發生! – DavidG

+1

對於問題的第二部分,您可能需要閱讀++上的文檔:https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/increment-operator。 'counter ++'在遞增之前返回計數器。 – Chris

+4

您在調試時多次枚舉'test',導致'counter'遞增。 – Lee

回答

2

輸出不斷變化的原因是,test實際上並不計算,直到你通過它枚舉。因此打開調試視圖會導致它評估枚舉。然後每次枚舉它時,它都會再次運行,每次變量都會增加。因此,您可以多次運行for循環或多次打印test.First(),以獲得一些有趣的結果。

可以防止這種通過強制枚舉兌現到一個列表:

var test = array.Select(a => counter++).ToList(); 
//          ^^^^^^^^^ 

至於爲什麼它開始於零,這是因爲++在這方面是一個遞增運算符,這意味着它返回值然後遞增。如果你想讓它從1開始,代之以變量前綴:

var test = array.Select(a => ++counter).ToList(); 
+0

這大概是我的想法,但有一點我不確定的是,爲什麼'test'的結果是10-14,這意味着計數器已經增加了那麼高,但是'counter'本身顯示了5.是否調試器故意不實際堅持更改計數器評估枚舉或什麼的?它看起來並不需要清爽(當它認爲它們不是最新的時候,它通常會讓事情變得灰暗)。 – Chris

+0

@Chris'計數器'應該先被評估,然後在擴展結果視圖後進行測試。 'counter'的值不會在視圖中自動更新,直到執行一行代碼。 – DavidG

+0

因此,這表明它評估'測試'兩次,然後由於某種原因 - 一旦返回5-9,因爲計數器從5開始,然後第二次返回我們看到的10-14? – Chris

1

這很正常。當你使用Select方法時,你會得到一個懶惰的列表,這意味着它將在你訪問它時被評估。在這裏,你可以訪問它兩次,當你執行foreach,並且當你看着調試器時,每次你選擇的Func都會被執行,從而增加你的計數器。 如果通過

var test = array.Select(a => counter++).ToList(); 

取代它不會偷懶了,當你調用ToList會被執行一次()。然而,保持懶惰可能會很有趣,特別是如果你想稍後添加一些條件,例如追加一些Where條件,你不會希望在完成構建之前執行查詢。

你的計數器從零開始,因爲counter ++會首先給你的值,然後只增加它。如果你想從一個開始,你可以將計數器初始化爲1或者用++計數器代替counter ++,它會先遞增然後返回。

相關問題