ไม่มีอะไรผิดปกติกับการใช้ตัวแปรตัวนับ ในความเป็นจริงไม่ว่าคุณจะใช้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
ช่วยให้คุณรำคาญโดยเฉพาะ ... หากคุณต้องการข้ามรายการเพียงใช้ a continue
ในร่างกายของลูป
และเพื่อความสมบูรณ์ทั้งนี้ขึ้นอยู่กับสิ่งที่คุณทำกับดัชนีของคุณ (โครงสร้างด้านบนมีความยืดหยุ่นมากมาย) คุณอาจใช้ 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
เนื่องจากคุณยังคงใช้เธรดเดี่ยวสำหรับไวยากรณ์ที่น่าเกลียด