Untuk apa ApplicationException di .NET?

172

Untuk melempar pengecualian, saya biasanya menggunakan kelas pengecualian bawaan, misalnya ArgumentNullExceptiondan NotSupportedException. Namun, terkadang saya perlu menggunakan pengecualian khusus dan dalam kasus itu saya menulis:

class SlippedOnABananaException : Exception { }
class ChokedOnAnAppleException : Exception { }

dan seterusnya. Lalu saya melempar dan menangkap ini dalam kode saya. Tapi hari ini saya menemukan ApplicationExceptionkelas - haruskah saya menggunakannya? Untuk apa ini?

Tampaknya tidak efisien untuk memiliki banyak kelas Pengecualian yang identik secara efektif identik dengan nama yang berbeda (saya biasanya tidak memerlukan fungsionalitas individu). Tapi saya tidak suka ide menangkap generik ApplicationExceptiondan harus menggunakan kode tambahan untuk menentukan apa kesalahannya.

Di mana harus ApplicationExceptioncocok dengan kode saya?

James
sumber

Jawaban:

100

Menurut komentar di msdn:

Aplikasi pengguna, bukan runtime bahasa umum, melemparkan pengecualian khusus yang berasal dari kelas ApplicationException. Kelas ApplicationException membedakan antara pengecualian yang ditentukan oleh aplikasi versus pengecualian yang ditentukan oleh sistem.

Jika Anda mendesain aplikasi yang perlu membuat pengecualian sendiri, Anda disarankan untuk mendapatkan pengecualian khusus dari kelas Exception. Awalnya dianggap bahwa pengecualian khusus harus berasal dari kelas ApplicationException; Namun dalam praktiknya ini belum ditemukan untuk menambah nilai signifikan. Untuk informasi lebih lanjut, lihat Praktik Terbaik untuk Menangani Pengecualian.

Turunkan mereka dari Exception. Juga, saya tidak melihat masalah dengan membuat pengecualian baru untuk kasus Anda, selama itu dibenarkan. Jika Anda menemukan kasus di mana sudah ada pengecualian dalam kerangka kerja, gunakan itu, jika tidak, gulung sendiri.

Femaref
sumber
9
Jadi sepertinya itu ApplicationExceptiontidak berguna dan apakah ada hanya karena kompatibilitas ke belakang?
Beatles1692
Dokumentasi MSDN baru, setidaknya 4.7.2, melewatkan komentar ini. Terima kasih untuk qutoe: D
Alex
147

Jawaban singkatnya adalah: tidak ada tempat.

Ini adalah peninggalan masa lalu, di mana Microsoft bermaksud pengembang untuk mewarisi semua pengecualian khusus dari ApplicationException. Tak lama kemudian, mereka berubah pikiran dan menyarankan bahwa pengecualian khusus harus berasal dari kelas Pengecualian dasar. Lihat Praktik Terbaik untuk Menangani Pengecualian di MSDN.

Salah satu alasan yang lebih luas beredar untuk ini berasal dari kutipan dari Jeffery Richter dalam Kerangka Desain Pedoman :

System.ApplicationException adalah kelas yang tidak boleh menjadi bagian dari .NET Framework. Gagasan asli adalah bahwa kelas yang berasal dari SystemException akan menunjukkan pengecualian yang dikeluarkan dari CLR (atau sistem) itu sendiri, sedangkan pengecualian non-CLR akan berasal dari ApplicationException . Namun, banyak kelas pengecualian tidak mengikuti pola ini. Misalnya, TargetInvocationException (yang dilemparkan oleh CLR) berasal dari ApplicationException . Jadi, kelas ApplicationException kehilangan semua makna. Alasan untuk mendapatkan dari kelas dasar ini adalah untuk memungkinkan beberapa kode lebih tinggi dari tumpukan panggilan untuk menangkap kelas dasar. Tidak mungkin lagi menangkap semua pengecualian aplikasi.

Jadi begitulah. Ringkasan eksekutif adalah bahwa ApplicationException tidak berbahaya , hanya tidak berguna .

Joe Smith Cepat
sumber
2
Adakah yang tahu mengapa itu terjadi? Sepertinya masuk akal sehingga Anda bisa menampilkan pengecualian Aplikasi tetapi tidak pengecualian "programmer kacau".
Josh Kodroff
9
BTW, tampaknya dari penjelasan ini bahwa ini bukan desain yang buruk tapi itu MSFT mengacaukan implementasi. Apakah ada orang lain yang membaca ini dengan cara yang sama?
Josh Kodroff
8
@JoshKodroff: Saya pikir masalahnya adalah jika aplikasi Whizbangmemutuskan bahwa ia ingin memiliki semua pengecualian di bawah beberapa hierarki umum, menggunakan ApplicationExceptionuntuk tujuan itu akan benar-benar tidak menawarkan keuntungan dibandingkan menggunakan WhizbangExceptionkelas dasar kustom . Namun, masalah yang lebih serius dalam hierarki pengecualian .net tidak ada pada ApplicationException, namun dengan kegagalan memisahkan pengecualian ke dalam kategori yang mungkin terkait dengan aplikasi, fatal, fatal, dan terkait masalah lokal, serta ketidakmampuan untuk memiliki pengecualian "komposit" yang berarti.
supercat
@JoshKodroff: Dalam kerangka pengecualian yang dirancang dengan benar, IMHO, jika pengecualian dilemparkan selama finallyblok sementara pengecualian lain sedang tertunda, catchblok lebih jauh ke tumpukan panggilan harus dipicu jika mereka cocok dengan pengecualian bersarang, tetapi meninggalkan pengecualian lain yang tertunda sehingga keluar sebuah catchblok akan dilanjutkan ke catchblok lain dalam blok yang sama try(jika ada yang cocok), dan keluar dari finallyblok dengan pengecualian yang tertunda akan melompat ke luar catchatau berikutnya finally.
supercat
2
@JoshKodroff Ada satu hal lagi yang saya terkejut tidak mendapat perhatian lebih. Apa sebenarnya "aplikasi" itu? Bagaimana dengan perpustakaan pihak ketiga ? Karena ini bukan bagian dari kerangka. Net, mereka harus dengan pedoman asli yang diwarisi dari ApplicationException. Sekarang ketika Anda menggunakan perpustakaan itu di aplikasi Anda dan juga membuat Anda sendiri ApplicationExceptions, Anda tidak bisa lagi melihat pengecualian Anda sendiri dari pengecualian perpustakaan berdasarkan itu. Jadi tidak ada gunanya. Sebagai gantinya, setiap komponen harus mendefinisikan tipe basis pengecualiannya sendiri, seperti yang dijelaskan supercat.
Oskar Berggren
22

Dalam desain awal, dalam. NET 1.0, direncanakan bahwa kerangka itu sendiri akan dibuang SystemExceptiondan diturunkan; sementara aplikasi pengguna - akan melempar ApplicationExceptiondan diturunkan.

Tetapi kemudian, dalam. NET 2.0, itu dijatuhkan.

Jadi berasal dari Exception.

abatishchev
sumber