一、使用list.Remove()
1.在foreach和list.ForEach中使用list.Remove()
在foreach中是不能使用list.Remove(),否则在进入下一个循环就会报异常,所以,如果有使用之后就必须break;
在.ForEach()中,要注意,在.net framework 4.5 会报异常:集合已修改;可能无法执行枚举操作。在.net framework4 3.5 3.0 2.0这几个版本下,可以直接使用list.Remove(),但如果在使用Remove()后下一项是不会遍历到,会自动用下下项。如下代码:
Listlist = new List (){ new Person(){ Id=1,Name="1"}, new Person(){ Id=2,Name="2"}, new Person(){ Id=3,Name="3"}, new Person(){ Id=4,Name="4"}, }; list.ForEach(item => { Console.WriteLine(string.Format("111--Id:{0},Name:{1}", item.Id, item.Name)); if (item.Id == 2) { list.Remove(item); item.Id = item.Id * 10; } item.Id = item.Id * 10; Console.WriteLine(string.Format("222--Id:{0},Name:{1}", item.Id, item.Name)); }); Console.WriteLine("------------"); list.ForEach(item => Console.WriteLine(string.Format("Id:{0},Name:{1}", item.Id, item.Name)));
结果:
111--Id:1,Name:1
222--Id:10,Name:1
111--Id:2,Name:2
222--Id:200,Name:2
111--Id:4,Name:4
222--Id:40,Name:4
------------
Id:10,Name:1
Id:3,Name:3
Id:40,Name:4
就是在id=2这项remove后还会对这项进行操作,但在进入下一项是id=4,而id=3这项没有遍历到
所以如果想删除id=2和id=3这两项,结果是id=3是删除不了,如下:
list.ForEach(item =>
{
if (item.Id == 2 || item.Id==3)
{
list.Remove(item);
}
});
list.ForEach(item => Console.WriteLine(string.Format("Id:{0},Name:{1}", item.Id, item.Name)));
结果:
Id:1,Name:1
Id:3,Name:3
Id:4,Name:4
只删除了id=2这项,所以想删除list中的项,最好还是用for
for (int i = 0; i < list.Count; i++)
{
if (list[i].Id == 2 || list[i].Id == 3)
{
list.Remove(list[i]);
i--;
}
}
注意删除后,i--;
或者使用list.RemoveAll(),如下:
list.RemoveAll(item => { return item.Id == 2 || item.Id == 3; });
list.ForEach(item => Console.WriteLine(string.Format("Id:{0},Name:{1}", item.Id, item.Name)));
所以,想删除list中的项,最好不用使用foreach和list.ForEach,而是使用for或list.RemoveAll
2.在list.ForEach()中不能使用continue或者break
如果在遍历到某个特殊项的时候,不用遍历后面的项,需要break,这种情况使用foreach
3.list.ForEach()的使用
foreach的使用就不说了。
看一下msdn上对list.ForEach的参数的说明:
System.Action
要对 List
Action
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
List names = new List();
names.Add("Bruce");
names.Add("Alfred");
names.Add("Tim");
names.Add("Richard");
// Display the contents of the list using the Print method.
names.ForEach(Print);
// The following demonstrates the anonymous method feature of C#
// to display the contents of the list to the console.
names.ForEach(delegate(String name)
{
Console.WriteLine(name);
});
}
private static void Print(string s)
{
Console.WriteLine(s);
}
}
所以,如果有需要用到委托方法,可以使用list.ForEach
平时使用list.ForEach一般都是用Lambda 表达式
二、性能
简单写了一个测试代码,循环一千万次,看下所用时间:
Listlist = new List (); for (int i = 0; i < 10000000; i++) { list.Add(new Person() { Id = i, Name = i.ToString() }); } Stopwatch watch = new Stopwatch(); watch.Start(); foreach (var item in list) { item.Id = item.Id + 1; } watch.Stop(); Console.WriteLine(string.Format("foreach执行时间:{0}", watch.Elapsed)); watch = new Stopwatch(); watch.Start(); list.ForEach(item => { item.Id = item.Id + 1; }); watch.Stop(); Console.WriteLine(string.Format("list.ForEach执行时间:{0}", watch.Elapsed)); watch = new Stopwatch(); watch.Start(); for (int i = 0; i < list.Count; i++) { list[i].Id = list[i].Id + 1; } watch.Stop(); Console.WriteLine(string.Format("for1执行时间:{0}", watch.Elapsed)); watch = new Stopwatch(); watch.Start(); int count = list.Count; for (int i = 0; i < count; i++) { list[i].Id = list[i].Id + 1; } watch.Stop(); Console.WriteLine(string.Format("for2执行时间:{0}", watch.Elapsed));
结果:
foreach执行时间:00:00:00.2760314
list.ForEach执行时间:00:00:00.2458242
for1执行时间:00:00:00.3641918
for2执行时间:00:00:00.1642685
效率最高是for2,for1和for2区别看代码就知道了,list.ForEach会比foreach略快一点,但差别并不大,所以在使用foreach和list.ForEach上可以不考虑性能上的差异。
总结,foreach和list.ForEach在性能上差异不大,在使用上实际也不会有很多差别,只是在几个特殊使用上会有所不同,但list.ForEach代码看上去会更新简洁一些。



