Seperti yang saya pahami, dalam Linq metode FirstOrDefault()
dapat mengembalikan Default
nilai selain null. Apa yang saya belum berhasil adalah hal-hal apa selain null dapat dikembalikan dengan metode ini (dan serupa) ketika tidak ada item dalam hasil permintaan. Apakah ada cara tertentu yang dapat diatur sehingga jika tidak ada nilai untuk permintaan tertentu beberapa nilai yang telah ditentukan dikembalikan sebagai nilai default?
142
YourCollection.FirstOrDefault()
, Anda bisa menggunakanYourCollection.DefaultIfEmpty(YourDefault).First()
misalnya.MyCollection.Last().GetValueOrDefault(0)
untuk itu. Kalau tidak, @Jon Skeet jawaban di bawah ini adalah IMO benar.Jawaban:
Kasus umum, bukan hanya untuk tipe nilai:
Sekali lagi, ini tidak bisa benar-benar tahu jika ada adalah sesuatu dalam urutan Anda, atau jika nilai pertama adalah default.
Jika Anda peduli tentang ini, Anda bisa melakukan sesuatu seperti
dan gunakan sebagai
meskipun seperti yang ditunjukkan oleh Mr. Steak, ini bisa dilakukan juga oleh
.DefaultIfEmpty(...).First()
.sumber
<T>
dalam nama mereka, tetapi yang lebih serius adalah ituvalue == default(T)
tidak berhasil (karena siapa yang tahu jikaT
dapat dibandingkan untuk kesetaraan?)EqualityComparer<T>.Default.Equals(value, default(T))
untuk menghindari tinju dan menghindari pengecualian jika nilainyanull
Tidak. Atau lebih tepatnya, selalu mengembalikan nilai default untuk jenis elemen ... yang merupakan referensi nol, nilai nol dari jenis nilai yang dapat dibatalkan, atau nilai "semua nol" yang alami untuk jenis nilai yang tidak dapat dibatalkan.
Untuk jenis referensi, Anda bisa menggunakan:
Tentu saja ini juga akan memberi Anda "nilai default lain" jika nilai pertama ada, tetapi merupakan referensi nol ...
sumber
int
. Saya lebih memilih penggunaanDefaultIfEmpty
:src.Where(filter).DefaultIfEmpty(defaultValue).First()
. Berfungsi untuk tipe nilai dan tipe referensi.Anda dapat menggunakan DefaultIfEmpty diikuti oleh Pertama :
sumber
DefaultIfEmpty
- bekerja dengan semua API yang perlu default yang akan ditentukan:First()
,Last()
, dll Sebagai pengguna, Anda tidak perlu mengingat yang API memungkinkan untuk menentukan standar yang tidak. Sangat elegan!Dari dokumentasi untuk FirstOrDefault
Dari dokumentasi untuk default (T) :
Oleh karena itu, nilai default bisa nol atau 0 tergantung pada apakah tipe tersebut adalah tipe referensi atau nilai, tetapi Anda tidak dapat mengontrol perilaku default.
sumber
Disalin dari komentar oleh @sloth
Alih-alih
YourCollection.FirstOrDefault()
, Anda bisa menggunakanYourCollection.DefaultIfEmpty(YourDefault).First()
misalnya.Contoh:
sumber
DefaultIfEmpty
mengembalikan default JIKA koleksi kosong (memiliki 0 item). Jika Anda menggunakanFirst
DENGAN ekspresi yang cocok seperti dalam contoh Anda dan kondisi itu tidak menemukan item apa pun nilai pengembalian Anda akan kosong.Anda juga bisa melakukan ini
Ini hanya menggunakan linq - yipee!
sumber
FirstOrDefault
sebagai gantiFirst
. Menurut msdn.microsoft.com/en-us/library/bb340482.aspx , penggunaan yang disarankan adalahFirst
Sebenarnya, saya menggunakan dua pendekatan untuk menghindari
NullReferenceException
ketika saya bekerja dengan koleksi:Untuk C # 6.0 atau yang lebih baru:
Gunakan
?.
atau?[
untuk menguji apakah nol sebelum melakukan akses anggota, dokumentasi Operator Null-kondisionalContoh:
var barCSharp6 = list.FirstOrDefault()?.Bar;
C # versi yang lebih lama:
Gunakan
DefaultIfEmpty()
untuk mengambil nilai default jika urutannya kosong. Dokumentasi MSDNContoh:
string barCSharp5 = list.DefaultIfEmpty(new Foo()).FirstOrDefault().Bar;
sumber
Alih-alih
YourCollection.FirstOrDefault()
, Anda bisa menggunakanYourCollection.DefaultIfEmpty(YourDefault).First()
misalnya.sumber
Saya baru saja mengalami situasi yang sama dan sedang mencari solusi yang memungkinkan saya untuk mengembalikan nilai default alternatif tanpa mengurusnya di sisi pemanggil setiap kali saya membutuhkannya. Apa yang biasanya kita lakukan seandainya Linq tidak mendukung apa yang kita inginkan, adalah menulis ekstensi baru yang menanganinya. Itu yang saya lakukan. Inilah yang saya buat (belum diuji):
sumber
Saya tahu ini sudah lama tetapi saya akan menambahkan ini, berdasarkan jawaban yang paling populer tetapi dengan sedikit ekstensi ID ingin berbagi di bawah ini:
Ini memungkinkan saya untuk menyebutnya sebaris dengan contoh saya sendiri. Saya mengalami masalah dengan:
Jadi bagi saya, saya hanya ingin resolver default untuk digunakan inline, saya bisa melakukan pemeriksaan biasa dan kemudian meneruskan fungsi sehingga kelas tidak dipakai bahkan jika tidak digunakan, itu adalah fungsi untuk mengeksekusi ketika diperlukan sebagai gantinya!
sumber
Gunakan
DefaultIfEmpty()
sebagai gantiFirstOrDefault()
.sumber