![](/img/trans.png)
[英]Why can't I use LINQ to Objects when my class implements IEnumerable<T> multiple times?
[英]Why can't I change elements from a linq IEnumerable in a for loop?
昨天我寫了下面的c#代碼(為了易讀性而縮短了一點):
var timeObjects = ( from obj in someList
where ( obj.StartTime != null )
select new MyObject()
{
StartTime= obj.StartTime.Value,
EndTime = obj.EndTime
} )
因此每個項目都有一個startTime,有些項目有一個EndTime(其他項目有null作為EndTime)。
如果已知start和endtime,我想計算經過的時間:
foreach ( var item in timeObjects)
{
if ( item.EndTime == null )
{
item.elapsed = 0;
}
else
{
item.elapsed = ( item.EndTime.Value - item.StartTime).Minutes;
}
}
但這不起作用! timeObjects集合永遠不會改變。
如果我說:
var timeObjects = ( from obj in someList
where ( obj.StartTime != null )
select new MyObject()
{
StartTime= obj.StartTime.Value,
EndTime = obj.EndTime
} ).ToList();
foreach ( var item in timeObjects)
{
if ( item.EndTime == null )
{
item.elapsed = 0;
}
else
{
item.elapsed = ( item.EndTime.Value - item.StartTime).Minutes;
}
}
//(only change is the ToList() at the end of the linq statement)
它確實有效。
我非常想知道為什么會這樣?
你的timeObjects
是一個可枚舉的延遲執行。 如果您對列表進行兩次枚舉,則實際將對結果進行兩次計算,從而創建新對象。
當您執行ToList()時,它創建了該查詢/可枚舉的結果的本地副本,這就是您看到更改的原因。 這種LINQ查詢不會創建任何類型的列表。 在您枚舉查詢之前,不會執行查詢本身。 你在(from ... select)狀態下所做的就是創建查詢定義。
您的原始timeObjects定義定義了一個懶惰評估的LINQ表達式,因此每當您嘗試遍歷timeObjects可枚舉時,它將創建MyObject的新實例。
在調用ToList()之前,它似乎不是IEnumerable而是IQueryable ,因此對臨時對象進行了更改。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.