Apakah ada cara yang lebih baik untuk melakukan hal berikut:
Saya perlu memeriksa null untuk terjadi pada file. Header sebelum melanjutkan dengan loop
if (file.Headers != null)
{
foreach (var h in file.Headers)
{
//set lots of properties & some other stuff
}
}
Singkatnya, tampaknya agak jelek untuk menulis foreach di dalam if karena tingkat lekukan yang terjadi di kode saya.
Adalah sesuatu yang akan mengevaluasi
foreach(var h in (file.Headers != null))
{
//do stuff
}
bisa jadi?
Jawaban:
Hanya sebagai tambahan kosmetik untuk saran Rune, Anda dapat membuat metode ekstensi Anda sendiri:
public static IEnumerable<T> OrEmptyIfNull<T>(this IEnumerable<T> source) { return source ?? Enumerable.Empty<T>(); }
Kemudian Anda bisa menulis:
foreach (var header in file.Headers.OrEmptyIfNull()) { }
Ganti nama sesuai selera :)
sumber
Dengan asumsi bahwa jenis elemen dalam file.Headers adalah T, Anda dapat melakukan ini
foreach(var header in file.Headers ?? Enumerable.Empty<T>()){ //do stuff }
ini akan membuat enumerable T yang kosong jika file.Headers adalah null. Jika tipe file adalah tipe yang Anda miliki, saya akan, bagaimanapun, pertimbangkan untuk mengubah pengambil
Headers
alih - alih.null
adalah nilai tidak diketahui jadi jika memungkinkan daripada menggunakan null sebagai "Saya tahu tidak ada elemen" ketika null sebenarnya (/ aslinya) harus diartikan sebagai "Saya tidak tahu apakah ada elemen" gunakan set kosong untuk menunjukkan bahwa Anda tahu tidak ada elemen di himpunan. Itu juga akan lebih KERING karena Anda tidak perlu melakukan pemeriksaan null sesering mungkin.EDIT sebagai tindak lanjut dari saran Jons, Anda juga dapat membuat metode ekstensi dengan mengubah kode di atas menjadi
foreach(var header in file.Headers.OrEmptyIfNull()){ //do stuff }
Dalam kasus di mana Anda tidak dapat mengubah pengambil, ini akan menjadi pilihan saya sendiri karena ini mengungkapkan maksud lebih jelas dengan memberi nama operasi (OrEmptyIfNull)
Metode ekstensi yang disebutkan di atas mungkin membuat pengoptimalan tertentu tidak mungkin dideteksi oleh pengoptimal. Secara khusus, yang terkait dengan IList menggunakan metode overloading ini dapat dihilangkan
public static IList<T> OrEmptyIfNull<T>(this IList<T> source) { return source ?? Array.Empty<T>(); }
sumber
null
) menurunkan seluruh loop ke LCDIEnumerable<T>
(seperti menggunakan ?? akan), b) memerlukan penambahan Metode Ekstensi untuk setiap Proyek, atau c) memerlukan penghindarannull
IEnumerables
(Pffft! Puh-LEAZE! SMH.) untuk memulai (cuznull
berarti T / A, sedangkan daftar kosong berarti, itu berlaku tetapi saat ini, baik, kosong !, yaitu seorang Karyawan dapat memiliki Komisi yang N / A untuk non-Penjualan atau kosong untuk Penjualan ketika mereka belum memperolehnya).IEnumerable
yang lebih ketat daripadaforeach
persyaratan tetapi kurang ketat daripada persyaratanList<T>
dalam jawaban yang Anda tautkan. Yang memiliki hukuman kinerja yang sama untuk menguji apakah enumerable adalah null.List<T>
.Terus terang, saya menyarankan: menyedot saja
null
ujiannya. Sebuahnull
tes hanya sebuahbrfalse
ataubrfalse.s
; segala sesuatu yang lain akan melibatkan kerja lebih banyak (tes, tugas, metode ekstra panggilan, yang tidak perluGetEnumerator()
,MoveNext()
,Dispose()
pada iterator, dll).Sebuah
if
tes sederhana, jelas, dan efisien.sumber
"jika" sebelum iterasi baik-baik saja, beberapa dari semantik "cantik" tersebut dapat membuat kode Anda kurang dapat dibaca.
bagaimanapun, jika lekukan mengganggu Anda, Anda dapat mengubah jika untuk memeriksa:
if(file.Headers == null) return;
dan Anda akan sampai ke loop foreach hanya jika ada nilai true di properti headers.
opsi lain yang dapat saya pikirkan adalah menggunakan operator penggabungan-nol di dalam loop foreach Anda dan untuk sepenuhnya menghindari pemeriksaan nol. Sampel:
List<int> collection = new List<int>(); collection = null; foreach (var i in collection ?? Enumerable.Empty<int>()) { //your code here }
(ganti koleksi dengan objek / tipe Anda yang sebenarnya)
sumber
Menggunakan Null-conditional Operator dan ForEach () yang bekerja lebih cepat dari loop foreach standar.
Anda harus memasukkan koleksi ke Daftar.
listOfItems?.ForEach(item => // ... );
sumber
Saya menggunakan metode ekstensi kecil yang bagus untuk skenario ini:
public static class Extensions { public static IList<T> EnsureNotNull<T>(this IList<T> list) { return list ?? new List<T>(); } }
Mengingat bahwa Header adalah daftar tipe, Anda dapat melakukan hal berikut:
foreach(var h in (file.Headers.EnsureNotNull())) { //do stuff }
sumber
??
operator dan mempersingkat pernyataan pengembalian kereturn list ?? new List<T>;
null
dalam sampel Andafile.Headers.EnsureNotNull() != null
tidak diperlukan, dan bahkan salah?Untuk beberapa kasus, saya lebih memilih varian generik lain, dengan asumsi bahwa, sebagai aturan, konstruktor collection default mengembalikan instance kosong.
Akan lebih baik untuk menamai metode ini
NewIfDefault
. Ini bisa berguna tidak hanya untuk koleksi, jadi batasan jenisIEnumerable<T>
mungkin berlebihan.public static TCollection EmptyIfDefault<TCollection, T>(this TCollection collection) where TCollection: class, IEnumerable<T>, new() { return collection ?? new TCollection(); }
sumber