List.Foreach与C#的foreach的区别

几年前参加面试时就被提问过,现在面试别人时也经常提到这个问题。 今天小试了一下。得出如下几点:

1. 首先,mscorlib里System.Collections.Generic. List类里有如下方法说明:

        //
        // 摘要: 
        //     对 System.Collections.Generic.List 的每个元素执行指定操作。
        //
        // 参数: 
        //   action:
        //     要对 System.Collections.Generic.List 的每个元素执行的 System.Action 委托。
        //
        // 异常: 
        //   System.ArgumentNullException:
        //     action 为 null。
        public void ForEach(Action action);

2. 对于修改集合里的项时,两者都可以实现。

 
  
foreach (var item in list)
{
     item.ApplyNo = "testNo" + list.IndexOf(item);
}
list.ForEach(item => item.ApplyNo = "testNo" + list.IndexOf(item));

 

3. List.Foreach可以增删集合项,而foreach不行。

public static void Main()
{
    List list = new List();
    list.Add(new T_Info_PriorApplys() { });
    list.Add(new T_Info_PriorApplys() { });
    list.ForEach(item => item.ApplyNo = "testNo" + list.IndexOf(item));
    list.ForEach(p =>
    {
        if (p.ApplyNo == "testNo0")
        {
            list.Remove(p);
            list.Insert(0, new T_Info_PriorApplys { ApplyNo = "NewNo0-1" });
            list.Add(new T_Info_PriorApplys { ApplyNo = "NewNo0-2" });
        }

    });


    list.ForEach(item => Console.WriteLine(item.ApplyNo));
    Console.Read();
}

/* 运行结果:
NewNo0-1
testNo1
NewNo0-2
*/

需说明的是,使用Foreach时,当集合的元素增加后,由于索引器是从0开始的,新的元素如果在当前索引的后面,则也会参与遍历,如果在当前索引前,则当前元素会再次参与遍历。  所以, 如果在改变元素个数时没有条件, 会导致死循环。代码见下方:

list.ForEach(p =>
{
            list.Remove(p);
            list.Insert(0, new T_Info_PriorApplys { ApplyNo = "NewNo0-1" });
            list.Add(new T_Info_PriorApplys { ApplyNo = "NewNo0-2" });
});

 

用 foreach实现上面的逻辑时, 当新增完元素之后,下一次迭代时,会报异常 System.InvalidOperationException:集合已修改;可能无法执行枚举操作。

 List.Foreach与C#的foreach的区别_第1张图片

你可能感兴趣的:(List.Foreach与C#的foreach的区别)