Abstrak pengecualian tipe super

17

Jika melempar System.Exceptiondianggap sangat buruk, mengapa tidak Exceptiondilakukan abstractsejak awal?

Dengan begitu, tidak mungkin menelepon:

throw new Exception("Error occurred.");

Ini akan menegakkan menggunakan pengecualian turunan untuk memberikan rincian lebih lanjut tentang kesalahan yang terjadi.

Misalnya, ketika saya ingin memberikan hierarki pengecualian kustom untuk perpustakaan, saya biasanya mendeklarasikan kelas dasar abstrak untuk pengecualian saya:

public abstract class CustomExceptionBase : Exception
{
    /* some stuff here */
}

Dan kemudian beberapa pengecualian yang diturunkan dengan tujuan yang lebih spesifik:

public class DerivedCustomException : CustomExceptionBase
{
    /* some more specific stuff here */
}

Kemudian ketika memanggil metode pustaka apa pun, seseorang dapat meminta blok coba / tangkap generik ini untuk secara langsung menangkap kesalahan yang datang dari pustaka:

try
{
    /* library calls here */
}
catch (CustomExceptionBase ex)
{
    /* exception handling */
}

Apakah ini praktik yang baik?

Apakah lebih baik jika Exceptiondibuat abstrak?

EDIT: Maksud saya di sini adalah bahwa bahkan jika kelas pengecualian ditandai abstract, Anda masih bisa menangkapnya di blok tangkap semua. Menjadikannya abstrak hanyalah cara untuk melarang pemrogram untuk melemparkan pengecualian "super-lebar". Biasanya, ketika Anda secara sukarela melempar pengecualian, Anda harus tahu apa itu dan mengapa itu terjadi. Dengan demikian menegakkan untuk melemparkan jenis pengecualian yang lebih spesifik.

marco-fiset
sumber
3
+1 "Cara terbaik untuk mencegah penggunaan yang salah adalah membuat penggunaan seperti itu mustahil." - Scott Meyers
Steven Jeuris
3
"Apakah akan baik jika Pengecualian dibuat abstrak?" - Sama sekali tidak, karena semua kode .NET yang ada yang menggunakan Pengecualian baru ("...") akan rusak. Namun, "Haruskah tim NET membuat abstrak Exception sebagai permulaan?" - mungkin, ya, tapi sekarang sudah terlambat 10 tahun :)
MattDavey

Jawaban:

11

Saya tidak tahu alasan sebenarnya mengapa hal itu dilakukan dengan cara ini, dan pada tingkat tertentu saya setuju bahwa mencegah pengecualian yang sangat luas untuk dilempar akan menjadi hal yang baik.

TETAPI ... ketika mengkodekan aplikasi demo kecil atau pembuktian konsep, saya tidak ingin mulai mendesain 10 sub-kelas pengecualian yang berbeda, atau menghabiskan waktu untuk memutuskan mana yang merupakan kelas pengecualian "terbaik" untuk situasi tersebut. Saya lebih suka melempar Exceptiondan memberikan string yang menjelaskan detailnya. Ketika itu adalah kode yang dibuang, saya tidak peduli tentang hal-hal ini dan jika saya dipaksa untuk peduli dengan hal-hal seperti itu, saya akan membuat GenericExceptionkelas sendiri dan membuangnya di mana - mana, atau pindah ke alat / bahasa yang berbeda. Untuk beberapa proyek, saya setuju bahwa membuat subkelas Pengecualian yang relevan adalah penting, tetapi tidak semua proyek mengharuskannya.

FrustratedWithFormsDesigner
sumber
Saya sepenuhnya setuju dengan Anda, tetapi pertanyaannya adalah secara implisit memikirkan proyek yang tidak sepele.
marco-fiset
3

Kemungkinan A: Secara logis benar.

Anda benar bahwa Microsoft, dan banyak lainnya tidak menyarankan untuk melemparkan new Exception()langsung karena sejumlah alasan.

Karena itu, kita dapat mempertimbangkan cita-cita akademis bahwa tujuan Exceptionhierarki kelas adalah untuk menentukan efek penyempitan sehingga hanya pengecualian paling spesifik yang dapat ditangkap. (Yaitu ArgumentNullExceptionlebih sempit dari ArgumentException).

Kelas Exception tidak terkecuali (pun tidak dimaksudkan). Ini dimaksudkan sebagai pengecualian seluas mungkin, "pengecualian super" yang hampir tidak dapat ditangkap karena cakupannya sangat luas. 'Pengecualian' bukanabstract berarti Pengecualian tidak bisa eksis sebagai entitas sendiri. Ini dapat (meskipun diakui belum ada kasus yang baik didefinisikan - lihat Kemungkinan B), dan karena itu harus dapat dibangun secara publik.

Kata kunci 'abstrak' (dalam arti akademis murni) hanya berlaku ketika kelas dasar tidak masuk akal sendiri - yaitu FourLeggedAnimal.

Semua ini dalam pikiran, tidak akan ada alasan teknis untuk membuat kelas abstract, selain menjadi sumber kejengkelan bagi pengembang .

Kemungkinan B: Desain Terkunci / Mereka tidak tahu

Jika MS membuat kelas ini abstrak, mereka mungkin dalam masalah jika mereka berubah pikiran, karena kelas ini sangat penting untuk dasar-dasar bahasa. Mereka sudah melakukan kesalahan denganApplicationException , jadi dapat diperkirakan bahwa mereka mengantisipasi perubahan dalam rekomendasi juga. (lihat http://blogs.msdn.com/b/kcwalina/archive/2006/06/23/644822.aspx )

Mungkin ada alasan lain (saya pikir mungkin ini ada hubungannya dengan Reflection, atau beberapa alasan teknis lainnya), jadi saya membuat posting ini sebagai CW.

Kevin McCormick
sumber
"Hanya karena" super lebar ", itu tidak abstrak." ... Tapi itu argumen OP bukan? Bukankah seharusnya abstrak dalam arti bahwa beberapa indikasi jenis pengecualian selalu harus dilewati.
Steven Jeuris
Poin bagus, saya akan memperbarui jawaban saya sesuai - sifat pertanyaan ini agak membingungkan karena 'abstrak' adalah kata kunci bahasa sekaligus nama konsep yang sedang dibahas.
Kevin McCormick
@KevinMcCormick: Istilah 'abstrak' di sini digunakan sebagai kata kunci bahasa. Tolong beritahu saya bagaimana saya bisa mengubah pertanyaan saya sehingga lebih jelas untuk pembaca masa depan?
marco-fiset
Saya pikir ini pertanyaan yang bagus. Konversi OO apa pun mengenai abstractkata kunci mengenai dinding ini. Tidak yakin dengan cara apa pun untuk mengatasinya selain menunjukkan abstractkata kunci dengan backticks.
Kevin McCormick
2
Bagaimana "mengesampingkan" sebuah kelas merupakan perubahan besar?
konfigurator