Saya sering menemukan kode seperti berikut:
if ( items != null)
{
foreach(T item in items)
{
//...
}
}
Pada dasarnya, if
kondisi tersebut memastikan bahwa foreach
blok hanya akan dijalankan jika items
bukan null. Saya bertanya-tanya apakah if
kondisinya benar-benar diperlukan, atau foreach
akan menangani kasusnya jika items == null
.
Maksud saya, bisakah saya menulis
foreach(T item in items)
{
//...
}
tanpa khawatir apakah items
null atau tidak? Apakah if
kondisinya berlebihan? Atau ini tergantung pada jenis dari items
atau mungkin di T
juga?
null
) generalisasi seluruh lingkaran ke LCD dariEnumerable
(seperti menggunakan??
akan ), b) memerlukan penambahan Metode Ekstensi untuk setiap Proyek, atau c) memerlukan penghindarannull
IEnumerable
s (Pffft! Puh-LEAZE! SMH.) untuk memulai dengan (cuz,null
berarti N / A, sedangkan daftar kosong berarti, itu adalah appl. but is saat ini, yah, kosong !, yaitu seorang Karyawan dapat memiliki Komisi yang N / A untuk non-Penjualan atau kosong untuk Penjualan ketika mereka belum memperolehnya).Jawaban:
Anda masih perlu memeriksa apakah (items! = Null) jika tidak, Anda akan mendapatkan NullReferenceException. Bagaimanapun Anda dapat melakukan sesuatu seperti ini:
tetapi Anda mungkin memeriksa kinerjanya. Jadi saya masih lebih suka jika (item! = Null) dulu.
Berdasarkan saran Eric's Lippert, saya mengubah kode menjadi:
sumber
IEnumerable<T>
yang pada gilirannya menurunkan pencacah ke antarmuka membuat iterasi lebih lambat. Pengujian saya menunjukkan degradasi faktor 5 untuk iterasi melalui array int.Menggunakan C # 6 Anda dapat menggunakan operator bersyarat null baru bersama-sama dengan
List<T>.ForEach(Action<T>)
(atauIEnumerable<T>.ForEach
metode ekstensi Anda sendiri ).sumber
null
) menggeneralisasi seluruh loop ke LCDEnumerable
(seperti yang??
akan digunakan ), b) memerlukan penambahan Metode Ekstensi untuk setiap Proyek, atau c ) memerlukan penghindarannull
IEnumerable
s (Pffft! Puh-LEAZE! SMH.) untuk memulai dengan (cuz,null
artinya T / A, sedangkan daftar kosong berarti, itu berlaku. tetapi saat ini, yah, kosong !, yaitu sebuah Pekerjaan dapat memiliki Komisi yang T / A untuk non-Penjualan atau kosongkan untuk Penjualan ketika mereka belum memperolehnya).items
adalahList<T>
meskipun, bukan sembarangIEnumerable<T>
. (Atau memiliki metode ekstensi khusus, yang Anda katakan Anda tidak ingin ada ...) Selain itu, saya akan mengatakan itu benar-benar tidak layak menambahkan 11 komentar yang pada dasarnya mengatakan bahwa Anda menyukai jawaban tertentu.foreach
. Khususnya untuk List yang menurut saya akan diubah menjadifor
loop.Pengambilan sebenarnya di sini harus berupa urutan yang hampir tidak pernah boleh nol di tempat pertama . Cukup jadikan itu invarian di semua program Anda yang jika Anda memiliki urutan, itu tidak pernah nol. Itu selalu diinisialisasi menjadi urutan kosong atau urutan asli lainnya.
Jika suatu urutan tidak pernah nol maka jelas Anda tidak perlu memeriksanya.
sumber
null
) generalisasi seluruh lingkaran ke LCD dariEnumerable
(seperti menggunakan??
akan ), b) memerlukan penambahan Metode Ekstensi untuk setiap Proyek, atau c) memerlukan penghindarannull
IEnumerable
s (Pffft! Puh-LEAZE! SMH.) untuk memulai dengan (cuz,null
berarti N / A, sedangkan daftar kosong berarti, itu adalah appl. but is saat ini, yah, kosong !, yaitu seorang Karyawan dapat memiliki Komisi yang N / A untuk non-Penjualan atau kosong untuk Penjualan ketika mereka belum memperolehnya).Sebenarnya ada permintaan fitur pada @Connect itu: http://connect.microsoft.com/VisualStudio/feedback/details/93497/foreach-should-check-for-null
Dan tanggapannya cukup logis:
sumber
Anda selalu dapat mengujinya dengan daftar null ... tetapi ini yang saya temukan di situs msdn
sumber
Itu tidak berlebihan. Saat runtime, item akan dicor ke IEnumerable dan metode GetEnumeratornya akan dipanggil. Itu akan menyebabkan dereferensi item yang akan gagal
sumber
IEnumerable
dan 2) Ini adalah keputusan desain untuk membuatnya terlempar . C # dapat dengan mudah memasukkannull
cek itu jika pengembang menganggapnya sebagai ide yang bagus.Anda dapat merangkum pemeriksaan null dalam metode ekstensi dan menggunakan lambda:
Kode menjadi:
Jika bisa lebih ringkas jika Anda hanya ingin memanggil metode yang mengambil item dan mengembalikan
void
:sumber
Anda memang membutuhkan ini. Anda akan mendapatkan pengecualian saat
foreach
mengakses penampung untuk menyiapkan iterasi sebaliknya.Di bawah sampul,
foreach
menggunakan antarmuka yang diimplementasikan pada kelas koleksi untuk melakukan iterasi. Antarmuka umum yang setara ada di sini .sumber
Pengujian ini diperlukan, karena jika collectionnya null, foreach akan memunculkan NullReferenceException. Sebenarnya cukup mudah untuk mencobanya.
sumber
yang kedua akan melempar
NullReferenceException
dengan pesanObject reference not set to an instance of an object.
sumber
Seperti yang disebutkan di sini, Anda perlu memeriksa apakah itu bukan nol.
sumber
Di C # 6 Anda bisa menulis sth seperti ini:
Ini pada dasarnya adalah solusi Vlad Bezden tetapi menggunakan ?? ekspresi untuk selalu menghasilkan larik yang bukan nol dan oleh karena itu bertahan dari foreach daripada memiliki pemeriksaan ini di dalam braket foreach.
sumber