Perilaku yang diharapkan ketika permintaan untuk koleksi akan memiliki nol item

13

Katakanlah Anda diberi yang berikut ...

List<Thing> theThings = fubar.Things.All();

Jika tidak ada yang kembali, apa yang Anda harapkan dari fubar.

Sunting: Terima kasih atas pendapatnya. Saya akan menunggu sedikit dan menerima entri dengan maksimal.

Saya setuju dengan tanggapan sejauh ini, terutama yang menyarankan koleksi kosong. Vendor menyediakan API dengan beberapa panggilan yang mirip dengan contoh di atas. Vendor yang menghasilkan $ 4,6 juta pendapatan melalui API mereka tahun lalu, BTW. Mereka melakukan sesuatu yang pada dasarnya tidak saya setujui - mereka membuat pengecualian.

abscode
sumber
Tampaknya menjadi konsensus yang cukup solid [di sini] [1]: Koleksi kosong. Selalu. [1]: stackoverflow.com/questions/1969993/…
Jesse C. Slicer
Untuk tipe data apa Things? Jika masuk akal untuk memiliki Thingsbidang kembali nol, maka masuk akal bagi Anda untuk menerima pengecualian karena Anda tidak memeriksa nol sebelum panggilan Anda All(). Namun, saya setuju dengan orang-orang yang berpikir fubar.Thingsharus mengembalikan koleksi kosong bukan nol.
Colin D
Aku mengerti maksudmu, Colin. Dalam hal ini, Anda dapat menganggap Hal ada dan Semua () adalah statis. Pengecualian khusus untuk koleksi yang kosong, bukan alasan lain.
abscode
OMG mereka melempar pengecualian ...! o_O
Stuart Marks
Sekarang, pertanyaan yang lebih menarik adalah alasan apa yang bisa dilemparkan oleh siapa pun dalam kasus generik seperti ini, atau apa yang membuat kasus ini begitu istimewa untuk menjamin Pelemparan ??!
Martin Ba

Jawaban:

29

Dari dua kemungkinan (yaitu mengembalikan nullatau mengembalikan koleksi kosong) saya akan memilih mengembalikan koleksi kosong, karena memungkinkan penelepon untuk melewati pemeriksaan nilai yang dikembalikan. Alih-alih menulis ini

List<Thing> theThings = fubar.Things.All();
if (theThings != null) {
    for (Thing t : theThings) {
        t.doSomething();
    }
}

mereka akan dapat menulis ini:

List<Thing> theThings = fubar.Things.All();
for (Thing t : theThings) {
    t.doSomething();
}

Fragmen kode kedua ini lebih pendek dan lebih mudah dibaca, karena level nesting lebih rendah satu per satu.

dasblinkenlight
sumber
2
Saya pikir saya juga akan lebih mudah untuk memahami secara konseptual sebagai 'set kosong' (tidak ada item). Null adalah 'tidak ada set', yang sangat berbeda. (Ini juga harus mencakup hal-hal yang mustahil secara logis - himpunan semua item yang aneh yang bahkan harus kosong, bukan nol). Sejujurnya saya tidak yakin apa yang (secara logis) akan menjadi set nol ... (bahkan jika Anda melawan telanjang di sebuah pulau, harta Anda adalah set kosong, bukan nol)
Clockwork-Muse
@ X-Zero Tetapi jika Anda telanjang bulat, "barang bawaan di ransel" dapat mengembalikan set nol, karena Anda bahkan tidak memiliki tas punggung pada Anda. Itu bisa menjadi BackpackNotFoundException, tetapi hanya jika itu benar-benar tidak terduga. Seharusnya keadaan normal dalam, katakanlah, game survival pulau.
Izkata
Pemeriksaan nol tambahan adalah yang membantu saya tidur di malam hari.
Joel B
6

Saya harapkan daftar kosong. theThingsmasih akan menjadi objek, tetapi theThings.Countatau theThings.size()akan kembali 0.

David Hogue
sumber
5

Masalah desain seperti itu ditangani oleh pola Obyek Null

... Alih-alih menggunakan referensi nol untuk menyampaikan tidak adanya objek (misalnya, pelanggan yang tidak ada), seseorang menggunakan objek yang mengimplementasikan antarmuka yang diharapkan, tetapi yang badan metodenya kosong. Keuntungan dari pendekatan ini dibandingkan implementasi default yang berfungsi adalah bahwa Obyek Null sangat dapat diprediksi dan tidak memiliki efek samping: ia tidak melakukan apa-apa.

Misalnya, suatu fungsi dapat mengambil daftar file dalam direktori dan melakukan beberapa tindakan pada masing-masing. Dalam kasus direktori kosong, satu respons mungkin untuk melemparkan pengecualian atau mengembalikan referensi nol daripada daftar. Dengan demikian, kode yang mengharapkan daftar harus memverifikasi bahwa sebenarnya ada satu sebelum melanjutkan, yang dapat menyulitkan desain ...

Saran yang terutama berlaku dalam kasus Anda (kembali Listketika tidak ada Thing) adalah:

... Dengan mengembalikan objek nol (yaitu daftar kosong ) sebagai gantinya, tidak perlu memverifikasi bahwa nilai kembali sebenarnya adalah daftar. Fungsi panggilan mungkin hanya mengulang daftar sebagai normal, tidak melakukan apa-apa secara efektif. Namun demikian, masih mungkin untuk memeriksa apakah nilai kembali adalah objek nol (misalnya daftar kosong) dan bereaksi secara berbeda jika diinginkan.

agas
sumber
3

Anda harus, IMHO, mengembalikan nilai KOSONG. Saya tidak tahu tentang C #, tetapi di Jawa kami memiliki ini:

  List list = Collections.EMPTY_LIST;
  Set set = Collections.EMPTY_SET;
  Map map = Collections.EMPTY_MAP;

  // For the type-safe 
  List<String> s = Collections.emptyList();
  Set<Long> l = Collections.emptySet();
  Map<Date> d = Collections.emptyMap();

http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Collections.html

Marcelo Assis
sumber
1
Setara C # adalah Enumerable.Empty<T>(), yang mengembalikan yang kosong IEnumerable<T>(lihat msdn.microsoft.com/en-us/library/bb341042.aspx )
Avner Shahar-Kashtan
1
Dokumen saat ini ada di sini: docs.oracle.com/javase/7/docs/api/java/util/Collections.html - dokumen 1.4.2 sekarang berusia sekitar sepuluh tahun.
Stuart Marks
2

Saya akan mengembalikan koleksi kosong dengan mengembalikan nilai nol karena dengan begitu Anda dapat menghindari penulisan verifikasi nol dalam kode panggilan.


sumber
2

Dua solusi yang mereka maksudkan berbeda.

Jika hanya ada nol barang yang Anda kembalikan, Anda SELALU mengembalikan koleksi kosong! Ambil contoh daftar direktori. Jika tidak ada file di direktori Anda mengembalikan koleksi file kosong.

Di sisi lain, jika direktori tidak ada, itu tidak benar-benar tepat. "Aku tidak bisa mengembalikan apa pun" berarti sesuatu yang sama sekali berbeda. Dalam hal ini Anda harus mengembalikan null atau melemparkan pengecualian tergantung situasinya, jangan hanya mengembalikan koleksi kosong seperti tidak ada yang salah.

Bill K.
sumber
Penjelasan yang sangat masuk akal. Hasil yang dikembalikan tidak mencakup keadaan tidak valid, kami memiliki pengecualian untuk ini.
Ivaylo Slavov