Không có gì sai với việc sử dụng một biến truy cập là. Thực tế, cho dù bạn sử dụng for
, foreach
while
hoặc do
, biến số lượt truy cập phải được khai báo và tăng lên ở đâu đó.
Vì vậy, sử dụng thành ngữ này nếu bạn không chắc chắn nếu bạn có một bộ sưu tập phù hợp-lập chỉ mục:
var i = 0;
foreach (var e in collection) {
// Do stuff with 'e' and 'i'
i++;
}
Else sử dụng này nếu bạn biết rằng indexable sưu tập của bạn là O (1) để truy cập chỉ mục (mà nó sẽ được cho Array
và có lẽ cho List<T>
(các tài liệu không nói), nhưng không nhất thiết với nhiều loại khác (chẳng hạn như 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'
}
Không bao giờ cần thiết phải 'thủ công' hoạt động IEnumerator
bằng cách gọi MoveNext()
và thẩm vấn Current
- foreach
giúp bạn tiết kiệm một số sự cố cụ thể ... nếu bạn cần bỏ qua các mục, chỉ cần sử dụng continue
trong phần thân của vòng lặp.
Và chỉ cho đầy đủ, tùy thuộc vào những gì bạn đã làm với chỉ số của bạn (các cấu trúc ở trên cung cấp nhiều linh hoạt), bạn có thể sử dụng LINQ Parallel:
// 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));
Chúng tôi sử dụng AsParallel()
trên, bởi vì nó Năm 2014 đã và chúng tôi muốn tận dụng tốt những lõi này để tăng tốc mọi thứ. Hơn nữa, đối với 'tuần tự' LINQ, you only get a ForEach()
extension method on List<T>
and Array
... và không rõ ràng rằng việc sử dụng nó tốt hơn so với thực hiện đơn giản foreach
, vì bạn vẫn đang chạy một luồng cho cú pháp xấu xí hơn.
foreach casting retrieval thường không giúp tôi tối ưu hóa nhiều hơn là chỉ sử dụng truy cập dựa trên chỉ mục trên một bộ sưu tập, mặc dù trong nhiều trường hợp nó sẽ bằng nhau. Mục đích của foreach là làm cho mã của bạn có thể đọc được, nhưng nó (thường) thêm một lớp của sự hướng dẫn, mà không phải là miễn phí. – Brian
Tôi sẽ nói mục đích chính của 'foreach' là cung cấp một cơ chế lặp lại chung cho tất cả các bộ sưu tập bất kể chúng có thể lập chỉ mục (' List') hay không ('Dictionary'). –
Xin chào Brian Gideon - chắc chắn đồng ý (đây là một vài năm trước và tôi đã ít kinh nghiệm hơn vào thời điểm đó). Tuy nhiên, trong khi 'Dictionary' không thể lập chỉ mục, một lần lặp lại của' Dictionary' không đi qua nó theo một thứ tự cụ thể (tức là một Enumerator có thể lập chỉ mục bởi thực tế nó tạo ra các phần tử tuần tự). Theo nghĩa này, chúng ta có thể nói rằng chúng ta không tìm kiếm chỉ mục trong bộ sưu tập, mà là chỉ mục của phần tử được liệt kê hiện tại trong liệt kê (nghĩa là chúng ta đang ở phần tử đầu tiên hoặc thứ năm hoặc cuối cùng). –