![](/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.