为什么我不能在for循环中更改linq IEnumerable中的元素?

Jau*_*uco 6 c# linq

昨天我写了下面的c#代码(为了易读性而缩短了一点):

 var timeObjects = ( from obj in someList
                     where ( obj.StartTime != null )
                     select new MyObject()
                     {
                        StartTime= obj.StartTime.Value,
                        EndTime = obj.EndTime
                     } )
Run Code Online (Sandbox Code Playgroud)

因此每个项目都有一个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;
    }
}
Run Code Online (Sandbox Code Playgroud)

但这不起作用!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)
Run Code Online (Sandbox Code Playgroud)

它确实有效.

我非常想知道为什么会这样?

Ada*_*son 11

timeObjects的延迟执行是可枚举的.如果您对列表进行两次枚举,则实际将对结果进行两次计算,从而创建新对象.

当您执行ToList()时,它创建了该查询/可枚举的结果的本地副本,这就是您看到更改的原因.这种LINQ查询不会创建任何类型的列表.在您枚举查询之前,不会执行查询本身.你在(from ... select)状态下所做的就是创建查询定义.