Jika saya menggunakan pernyataan switch untuk menangani nilai dari enum (yang dimiliki oleh kelas saya) dan saya memiliki case untuk setiap nilai yang mungkin - apakah ada baiknya menambahkan kode untuk menangani case "default"?
enum MyEnum
{
MyFoo,
MyBar,
MyBat
}
MyEnum myEnum = GetMyEnum();
switch (myEnum)
{
case MyFoo:
DoFoo();
break;
case MyBar:
DoBar();
break;
case MyBat:
DoBat();
break;
default:
Log("Unexpected value");
throw new ArgumentException()
}
Saya tidak berpikir itu karena kode ini tidak pernah dapat dicapai (bahkan dengan tes unit). Rekan kerja saya tidak setuju dan menganggap ini melindungi kami dari perilaku tak terduga yang disebabkan oleh nilai-nilai baru yang ditambahkan ke MyEnum.
Bagaimana kabarmu, komunitas?
MyEnum
kemudian melewati sakelar Anda?switch
pernyataan sepenuhnya.Jawaban:
Menyertakan case default tidak mengubah cara kode Anda bekerja, tetapi itu membuat kode Anda lebih mudah dikelola. Dengan membuat pemecah kode dengan cara yang jelas (mencatat pesan dan melemparkan pengecualian), Anda menyertakan panah merah besar untuk pekerja magang yang disewa perusahaan Anda musim panas mendatang untuk menambahkan beberapa fitur. Panah mengatakan: "Hei, kamu! Ya, saya sedang berbicara dengan ANDA! Jika Anda akan menambahkan nilai lain ke enum, Anda sebaiknya menambahkan kasus di sini juga." Upaya ekstra itu dapat menambahkan beberapa byte ke program yang dikompilasi, yang merupakan sesuatu yang perlu dipertimbangkan. Tapi itu juga akan menyelamatkan seseorang (mungkin bahkan masa depan Anda) di suatu tempat antara satu jam dan satu hari dari menggaruk-garuk kepala tidak produktif.
Pembaruan: Situasi yang dijelaskan di atas, yaitu melindungi terhadap nilai-nilai yang ditambahkan ke enumerasi di beberapa waktu kemudian, juga dapat ditangkap oleh kompiler. Dentang (dan gcc, saya pikir) secara default akan mengeluarkan peringatan jika Anda mengaktifkan jenis yang disebutkan tetapi tidak memiliki kasus yang mencakup setiap nilai yang mungkin dalam enumerasi. Jadi, misalnya, jika Anda menghapus
default
kasing dari sakelar dan menambahkan nilai baruMyBaz
ke enumerasi, Anda akan mendapatkan peringatan yang mengatakan:Membiarkan kompiler mendeteksi kasus yang tidak terungkap adalah bahwa sebagian besar menghilangkan kebutuhan untuk
default
kasus yang tidak terjangkau yang menginspirasi pertanyaan Anda.sumber
Saya baru saja berbicara dengan rekan kerja tentang hal ini pagi ini - sangat disayangkan, tetapi saya pikir penanganan standar diperlukan untuk keselamatan, karena dua alasan:
Pertama, seperti rekan kerja Anda sebutkan, itu membuktikan di masa depan kode terhadap nilai-nilai baru yang ditambahkan ke enum. Ini mungkin atau mungkin tidak tampak seperti suatu kemungkinan, tetapi selalu ada.
Lebih penting lagi, tergantung pada bahasa / kompiler, dimungkinkan untuk memiliki nilai-nilai yang bukan anggota enum dalam variabel diaktifkan Anda. Misalnya, dalam C #:
Dengan menambahkan
case default:
pengecualian sederhana dan melemparkan, Anda telah melindungi diri terhadap kasus aneh ini di mana "tidak ada" yang terjadi tetapi "sesuatu" seharusnya terjadi.Sayangnya, pada dasarnya setiap kali saya menulis pernyataan beralih lagi, itu karena saya sedang memeriksa kasus enum. Saya benar-benar berharap perilaku "melempar secara default" dapat ditegakkan oleh bahasa itu sendiri (setidaknya dengan menambahkan kata kunci).
sumber
Menambahkan kasing standar meskipun Anda tidak pernah berharap untuk mencapainya, itu bisa menjadi hal yang baik. Ini akan membuat proses debug jauh lebih mudah jika kode Anda melontarkan perkecualian "Ini seharusnya tidak terjadi" segera daripada nanti dalam program, menyadap beberapa pengecualian misterius atau mengembalikan hasil yang tidak terduga tanpa kesalahan.
sumber
Saya katakan:
Coba tambahkan jenis lain ke
MyEnum
. Kemudian ubah baris ini:untuk
Kemudian jalankan kode Anda dengan kasing standar dan tanpa kasing standar. Perilaku mana yang Anda sukai?
Memiliki case default juga dapat berguna untuk menjebak
NULL
nilai dan mencegahnyaNullPointerExceptions
.sumber
Jika Anda tahu bagaimana waktu mesin dapat dihemat dengan bersikeras pada kasus default, Anda tidak perlu mengajukan pertanyaan. Diam-diam melakukan apa pun dalam kondisi kesalahan tidak dapat diterima - apakah Anda diam-diam menangkap pengecualian yang seharusnya tidak pernah terjadi? Meninggalkan "ranjau" untuk pemrogram yang mengikuti Anda, juga tidak dapat diterima.
Jika kode Anda tidak akan pernah diubah atau dimodifikasi, dan 100% bebas bug, meninggalkan case default mungkin OK.
Ada (kakek dari bahasa pemrograman yang kuat) tidak akan mengkompilasi switch pada enum, kecuali semua enum tercakup atau ada pengendali default - fitur ini ada dalam daftar keinginan saya untuk setiap bahasa. Standar pengkodean Ada kami menyatakan bahwa dengan mengaktifkan enum, penanganan eksplisit semua nilai, tanpa standar adalah cara yang lebih disukai untuk menangani situasi ini.
sumber