使用计数器变量没有错。事实上,无论你用for
,foreach
while
或者do
,计数器变量必须某处声明和递增。
因此,如果不确定不确定是否有适当索引的集合,请使用以下惯用法:
var i = 0;
foreach (var e in collection) {
// Do stuff with 'e' and 'i'
i++;
}
否则,使用这一个,如果你知道你的可转位集合是O(1)索引访问(这将是Array
,可能为List<T>
(文档不说了),但不一定适合其他类型(如LinkedList
)):
// Hope the JIT compiler optimises read of the 'Count' property!
for (var i = 0; i < collection.Count; i++) {
var e = collection[i];
// Do stuff with 'e' and 'i'
}
永远不需要IEnumerator
通过调用MoveNext()
和询问来“手动”操作Current
- foreach
节省了您的麻烦……如果您需要跳过项目,只需continue
在循环体中使用a 。
为了完整起见,根据您对索引所做的操作(上述结构提供了很大的灵活性),您可以使用Parallel LINQ:
// First, filter 'e' based on 'i',
// then apply an action to remaining 'e'
collection
.AsParallel()
.Where((e,i) => /* filter with e,i */)
.ForAll(e => { /* use e, but don't modify it */ });
// Using 'e' and 'i', produce a new collection,
// where each element incorporates 'i'
collection
.AsParallel()
.Select((e, i) => new MyWrapper(e, i));
我们使用AsParallel()
上面的方法,因为已经是2014年了,我们希望充分利用这些多核来加快处理速度。此外,对于“顺序” LINQ,您只能ForEach()
在List<T>
和Array
... 上获得扩展方法,而且尚不清楚使用它比执行简单方法要好foreach
,因为您仍在使用单线程处理较丑陋的语法。