Tidak ada yang salah dengan menggunakan variabel penghitung. Bahkan, apakah Anda menggunakan for, foreach whileatau do, variabel counter harus dideklarasikan dan ditingkatkan di suatu tempat.
Jadi gunakan idiom ini jika Anda tidak yakin apakah Anda memiliki koleksi yang diindeks sesuai:
var i = 0;
foreach (var e in collection) {
// Do stuff with 'e' and 'i'
i++;
}
Lain gunakan yang ini jika Anda tahu bahwa koleksi Anda yang dapat diindeks adalah O (1) untuk akses indeks (yang akan untuk Arraydan mungkin untuk List<T>(dokumentasi tidak mengatakan), tetapi tidak harus untuk jenis lain (seperti 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'
}
Seharusnya tidak perlu untuk 'secara manual' mengoperasikannya IEnumeratordengan memohon MoveNext()dan menginterogasi Current- foreachmenyelamatkan Anda dari gangguan khusus itu ... jika Anda perlu melewatkan item, cukup gunakan a continuedi badan loop.
Dan hanya untuk kelengkapan, tergantung pada apa yang Anda lakukan dengan indeks Anda (konstruksi di atas menawarkan banyak fleksibilitas), Anda dapat menggunakan LINQ Paralel:
// 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));
Kami menggunakan di AsParallel()atas, karena ini sudah 2014, dan kami ingin memanfaatkan banyak inti untuk mempercepat. Lebih lanjut, untuk LINQ 'berurutan', Anda hanya mendapatkan ForEach()metode ekstensi List<T>danArray ... dan tidak jelas bahwa menggunakannya lebih baik daripada melakukan yang sederhana foreach, karena Anda masih menjalankan single-threaded untuk sintaks yang lebih buruk.