2013-01-16 52 views
1

這是一個驚喜,發現以下呼籲似乎沒有記住對該領域所做的改變。爲什麼不更改IEnumerable中的字段?

private void Foo(IEnumerable<Blopp> blopps) 
{ 
    foreach (Blopp blopp in blopps) 
    blopp.SomeField = PREFIX + blopp.SomeField; 

    String test = blopps.First().SomeField; 
} 

測試可變缺乏當使用LINQ到數據中得到的數組的前綴。我需要評估IEnumerable並使其成爲列表以便對域進行更改。爲什麼這樣?我希望程序能夠認識到的字段是,並且稍後會對其進行評估。

private void Foo(IEnumerable<Blopp> _blopps) 
{ 
    List<Blopp> blopps = _blopps.ToList(); 
    foreach (Blopp blopp in blopps) 
    blopp.SomeField = PREFIX + blopp.SomeField; 

    String test = blopps.First().SomeField; 
} 
+0

什麼是Blopp? –

+2

什麼是'_blopps'和'IEnumerbale'?使它成爲一個列表可能會解決動態生成的IEnumerable。 –

+0

@SteveB這是一個* class *類型的類。 –

回答

8

這取決於你傳遞給它的內容。如果這是一個懶惰評估序列,那麼每當您「看」blopps時,它將重新評估輸入。

如果你傳遞類似List<T>的東西,每次都會包含相同的確切值,所以沒關係。如果您傳遞一個無引用的查詢,則每次查看輸入時都會執行該查詢。是否返回與之前評估相同的對象的引用將取決於它在做什麼。 (如註釋中所述,在某些情況下,對一個評估返回的對象所做的更改甚至可以完全改變查詢的結果 - 可以修改對象,使得它們之前不會與過濾器匹配在查詢中。)

+0

我假設他有一個查詢,他想要改變的領域的過濾器,他正在改變'foreach',什麼也改變了查詢的結果。但是,每次評估都應該減少序列的Count(),並且不應該導致錯誤的結果。 –

+0

@TimSchmelter:這是另一種可能性,是的。基本上所有的東西都取決於輸入的確切性質。 –

+0

該死......建議執行* ToList *以防止這種情況發生?有更好的方法嗎? –

相關問題