Pol*_*olo 68 .net c# enumeration list enumerable
C#/ .NET 4.0中的一个新功能是,您可以在foreach不获取异常的情况下更改您的枚举.请参阅Paul Jackson的博客文章"并发的有趣副作用:在枚举时从集合中删除项目"以获取有关此更改的信息.
执行以下操作的最佳方法是什么?
foreach(var item in Enumerable)
{
foreach(var item2 in item.Enumerable)
{
item.Add(new item2)
}
}
Run Code Online (Sandbox Code Playgroud)
通常我使用IList一个缓存/缓冲区直到结束foreach,但是有更好的方法吗?
Rik*_*Rik 69
foreach中使用的集合是不可变的.这非常符合设计.
正如它在MSDN上所说:
foreach语句用于迭代集合以获取所需的信息,但不能用于添加或删除源集合中的项目以避免不可预测的副作用.如果需要在源集合中添加或删除项目,请使用for循环.
Poko提供的链接中的帖子表明在新的并发集合中允许这样做.
tva*_*son 15
在这种情况下使用IEnumerable扩展方法制作枚举的副本,并对其进行枚举.这会将每个内部可枚举中的每个元素的副本添加到该枚举中.
foreach(var item in Enumerable)
{
foreach(var item2 in item.Enumerable.ToList())
{
item.Add(item2)
}
}
Run Code Online (Sandbox Code Playgroud)
如上所述,但使用代码示例:
foreach(var item in collection.ToArray())
collection.Add(new Item...);
Run Code Online (Sandbox Code Playgroud)
为了说明Nippysaurus的答案:如果你要将新项目添加到列表中并且想要在同一枚举中处理新添加的项目,那么你可以使用for循环而不是foreach循环,问题解决了:)
var list = new List<YourData>();
... populate the list ...
//foreach (var entryToProcess in list)
for (int i = 0; i < list.Count; i++)
{
var entryToProcess = list[i];
var resultOfProcessing = DoStuffToEntry(entryToProcess);
if (... condition ...)
list.Add(new YourData(...));
}
Run Code Online (Sandbox Code Playgroud)
对于可运行的示例:
void Main()
{
var list = new List<int>();
for (int i = 0; i < 10; i++)
list.Add(i);
//foreach (var entry in list)
for (int i = 0; i < list.Count; i++)
{
var entry = list[i];
if (entry % 2 == 0)
list.Add(entry + 1);
Console.Write(entry + ", ");
}
Console.Write(list);
}
Run Code Online (Sandbox Code Playgroud)
最后一个例子的输出:
0,1,2,3,4,5,6,7,8,9,1,3,5,7,9,
清单(15项)
0
1
2
3
4
5
6
7
8
9
1
3
5
7
9
for()在这种情况下你真的应该使用而不是foreach()。