Dianjurkan untuk hanya menangkap System.Exception
. Sebaliknya, hanya pengecualian "diketahui" yang harus ditangkap.
Sekarang, ini terkadang mengarah pada kode berulang yang tidak perlu, misalnya:
try
{
WebId = new Guid(queryString["web"]);
}
catch (FormatException)
{
WebId = Guid.Empty;
}
catch (OverflowException)
{
WebId = Guid.Empty;
}
Saya bertanya-tanya: Apakah ada cara untuk menangkap kedua pengecualian dan hanya menelepon satu WebId = Guid.Empty
kali?
Contoh yang diberikan agak sederhana, karena hanya a GUID
. Tetapi bayangkan kode di mana Anda memodifikasi objek beberapa kali, dan jika salah satu manipulasi gagal dengan cara yang diharapkan, Anda ingin "mengatur ulang" itu object
. Namun, jika ada pengecualian yang tidak terduga, saya masih ingin membuang yang lebih tinggi.
c#
.net
exception
exception-handling
Michael Stum
sumber
sumber
AggregateException
: MelemparJawaban:
Tangkap
System.Exception
dan aktifkan tipenyasumber
EDIT: Saya setuju dengan orang lain yang mengatakan bahwa, pada C # 6.0, filter pengecualian sekarang merupakan cara yang baik untuk digunakan:
catch (Exception ex) when (ex is ... || ex is ... )
Kecuali bahwa saya masih agak benci tata letak garis panjang dan secara pribadi akan mengeluarkan kode seperti berikut. Saya pikir ini fungsional seperti estetika, karena saya percaya ini meningkatkan pemahaman. Beberapa mungkin tidak setuju:
ASLI:
Saya tahu saya sedikit terlambat ke pesta di sini, tetapi asap suci ...
Memotong langsung ke pengejaran, jenis ini menduplikasi jawaban sebelumnya, tetapi jika Anda benar-benar ingin melakukan tindakan umum untuk beberapa jenis pengecualian dan menjaga semuanya tetap rapi dan rapi dalam ruang lingkup satu metode, mengapa tidak hanya menggunakan lambda / closure / inline berfungsi untuk melakukan sesuatu seperti berikut ini? Maksud saya, peluangnya cukup bagus sehingga Anda akhirnya menyadari bahwa Anda hanya ingin membuat penutupan itu sebagai metode terpisah yang dapat Anda manfaatkan di semua tempat. Tetapi kemudian akan sangat mudah untuk melakukan itu tanpa benar-benar mengubah sisa kode secara struktural. Baik?
Saya tidak bisa menahan diri untuk bertanya-tanya ( peringatan: sedikit ironi / sarkasme di muka) mengapa harus melakukan semua upaya ini pada dasarnya hanya mengganti yang berikut ini:
... dengan beberapa variasi gila dari bau kode selanjutnya, maksud saya contoh, hanya untuk berpura-pura bahwa Anda menyimpan beberapa penekanan tombol.
Karena itu tentu saja tidak secara otomatis lebih mudah dibaca.
Memang, saya meninggalkan tiga contoh identik dari
/* write to a log, whatever... */ return;
contoh pertama.Tapi itu maksud saya. Kalian pernah mendengar fungsi / metode, kan? Serius. Tulis
ErrorHandler
fungsi umum dan, seperti, panggil dari masing-masing blok tangkapan.Jika Anda bertanya kepada saya, contoh kedua (dengan
if
danis
kata kunci) keduanya kurang terbaca secara signifikan, dan secara bersamaan lebih rentan terhadap kesalahan selama fase pemeliharaan proyek Anda.Fase pemeliharaan, bagi siapa saja yang mungkin relatif baru dalam pemrograman, akan mencapai 98,7% atau lebih dari keseluruhan masa hidup proyek Anda, dan orang bodoh yang melakukan pemeliharaan hampir pasti akan menjadi orang lain selain Anda. Dan ada kemungkinan yang sangat baik bahwa mereka akan menghabiskan 50% dari waktu mereka untuk pekerjaan mengutuk nama Anda.
Dan tentu saja FxCop menggonggong pada Anda dan Anda juga harus menambahkan atribut ke kode Anda yang memiliki persis zip terkait dengan program yang sedang berjalan, dan hanya ada di sana untuk memberitahu FxCop untuk mengabaikan masalah bahwa dalam 99,9% kasus itu benar-benar benar dalam menandai. Dan, maaf, saya mungkin salah, tetapi bukankah atribut "abaikan" itu benar-benar dikompilasi ke dalam aplikasi Anda?
Apakah menempatkan seluruh
if
tes pada satu baris membuatnya lebih mudah dibaca? Saya kira tidak. Maksud saya, saya punya programmer lain yang dengan keras berdebat sekali dulu bahwa menempatkan lebih banyak kode pada satu baris akan membuatnya "berjalan lebih cepat." Tapi tentu saja dia murka. Mencoba menjelaskan kepadanya (dengan wajah lurus - yang menantang) bagaimana penerjemah atau kompiler akan memecah garis panjang itu menjadi pernyataan satu-instruksi-per-garis yang terpisah - pada dasarnya identik dengan hasilnya jika ia terus maju dan hanya membuat kode dapat dibaca alih-alih mencoba mengompilasi kompiler - tidak berpengaruh padanya. Tapi saya ngelantur.Berapa banyak kurang dibaca tidak mendapatkan ini ketika Anda menambahkan tiga jenis pengecualian lebih, satu atau dua bulan dari sekarang? (Jawaban: itu mendapat banyak kurang dibaca).
Salah satu poin utama, sungguh, adalah bahwa sebagian besar titik memformat kode sumber tekstual yang kita semua lihat setiap hari adalah untuk membuatnya benar-benar jelas bagi manusia lain apa yang sebenarnya terjadi ketika kode dijalankan. Karena kompiler mengubah kode sumber menjadi sesuatu yang sama sekali berbeda dan tidak peduli tentang gaya pemformatan kode Anda. Jadi all-on-one-line benar-benar menyebalkan juga.
Hanya mengatakan ...
sumber
Exception
dan memeriksa tipenya. Saya pikir itu membersihkan kode, tetapi sesuatu membuat saya kembali ke pertanyaan dan saya benar-benar membaca jawaban lain untuk pertanyaan itu. Saya mengunyahnya sebentar, tetapi saya harus setuju dengan Anda. Hal ini lebih mudah dibaca dan dipertahankan untuk menggunakan fungsi untuk mengeringkan kode Anda daripada menangkap segala sesuatu, periksa jenis membandingkan terhadap daftar, kode pembungkus, dan lempar. Terima kasih telah datang terlambat dan menyediakan opsi alternatif dan waras (IMO). +1.throw;
. Anda harus mengulangi baris kode di setiap blok tangkap (jelas bukan akhir dunia tetapi layak disebutkan karena itu kode yang perlu diulang).throw();
pernyataan tambahan di setiap blok tangkap adalah harga kecil yang harus dibayar, IMO, dan masih membuat Anda berada dalam posisi untuk melakukan pembersihan pengecualian jenis khusus tambahan jika perlu.Func<Exception, MyEnumType>
alih-alihAction<Exception>
. ItuFunc<T, Result>
, denganResult
menjadi tipe pengembalian.Seperti yang telah ditunjukkan orang lain, Anda dapat memiliki
if
pernyataan di dalam blok penangkap untuk menentukan apa yang sedang terjadi. C # 6 mendukung Filter Pengecualian, jadi yang berikut ini akan berfungsi:The
MyFilter
Metode kemudian bisa terlihat seperti ini:Atau, ini semua bisa dilakukan inline (sisi kanan pernyataan when hanya harus menjadi ekspresi boolean).
Ini berbeda dari menggunakan
if
pernyataan dari dalamcatch
blok, menggunakan filter pengecualian tidak akan melepaskan tumpukan.Anda dapat mengunduh Visual Studio 2015 untuk melihatnya.
Jika Anda ingin terus menggunakan Visual Studio 2013, Anda dapat menginstal paket nuget berikut:
Pada saat penulisan, ini akan termasuk dukungan untuk C # 6.
sumber
Sayangnya tidak dalam C #, karena Anda memerlukan filter pengecualian untuk melakukannya dan C # tidak mengekspos fitur MSIL itu. VB.NET memang memiliki kemampuan ini, misalnya
Apa yang bisa Anda lakukan adalah menggunakan fungsi anonim untuk merangkum kode kesalahan Anda, dan kemudian menyebutnya di blok tangkapan khusus tersebut:
sumber
throw e;
menghancurkan stacktrace dan callstack,throw;
menghancurkan "hanya" callstack (menjadikan crash-dumps tidak berguna!) Alasan yang sangat baik untuk digunakan maupun jika dapat dihindari!Demi kelengkapan, karena .NET 4.0 kode dapat ditulis ulang sebagai:
TryParse tidak pernah melempar pengecualian dan mengembalikan false jika formatnya salah, mengatur WebId menjadi
Guid.Empty
.Karena C # 7 Anda dapat menghindari memperkenalkan variabel pada baris terpisah:
Anda juga dapat membuat metode untuk mem-parsing tupel yang kembali, yang belum tersedia di .NET Framework pada versi 4.6:
Dan gunakan seperti ini:
Pembaruan tidak berguna berikutnya untuk jawaban tidak berguna ini muncul ketika dekonstruksi parameter-out diimplementasikan dalam C # 12. :)
sumber
Guid.TryParse
tidak pernah kembaliGuid.Empty
. Jika string berada dalam format yang salah, ia mengaturresult
parameter outputGuid.Empty
, tetapi kembalifalse
. Saya menyebutkannya karena saya telah melihat kode yang melakukan hal-hal dalam gayaGuid.TryParse(s, out guid); if (guid == Guid.Empty) { /* handle invalid s */ }
, yang biasanya salah jikas
bisa menjadi representasi stringGuid.Empty
.if( Guid.TryParse(s, out guid){ /* success! */ } else { /* handle invalid s */ }
, yang tidak meninggalkan ambiguitas seperti contoh rusak di mana nilai input mungkin sebenarnya representasi string dari Guid.Filter pengecualian sekarang tersedia dalam c # 6+. Anda dapat melakukan
Di C # 7.0+, Anda dapat menggabungkan ini dengan pencocokan pola juga
sumber
Jika Anda dapat meningkatkan aplikasi ke C # 6, Anda beruntung. Versi C # yang baru telah menerapkan filter Pengecualian. Jadi Anda bisa menulis ini:
Beberapa orang berpikir kode ini sama dengan
Tapi ternyata tidak. Sebenarnya ini adalah satu-satunya fitur baru di C # 6 yang tidak mungkin ditiru di versi sebelumnya. Pertama, lemparan ulang berarti lebih banyak overhead daripada melewatkan tangkapan. Kedua, itu tidak setara secara semantik. Fitur baru mempertahankan tumpukan utuh ketika Anda men-debug kode Anda. Tanpa fitur ini, dump crash kurang berguna atau bahkan tidak berguna.
Lihat diskusi tentang ini di CodePlex . Dan contoh menunjukkan perbedaannya .
sumber
Jika Anda tidak ingin menggunakan
if
pernyataan dalamcatch
lingkup, diC# 6.0
Anda dapat menggunakanException Filters
sintaks yang sudah didukung oleh CLR dalam versi preview tetapi hanya ada diVB.NET
/MSIL
:Kode ini akan menangkap
Exception
hanya ketika ituInvalidDataException
atauArgumentNullException
.Sebenarnya, pada dasarnya Anda dapat meletakkan segala kondisi di dalam
when
klausa itu:Perhatikan bahwa sebagai lawan dari
if
pernyataan di dalamcatch
ruang lingkup,Exception Filters
tidak bisa melemparExceptions
, dan ketika mereka melakukannya, atau ketika kondisinya tidaktrue
,catch
kondisi selanjutnya akan dievaluasi sebagai gantinya:Ketika ada lebih dari satu
true
Exception Filter
- yang pertama akan diterima:Dan seperti yang Anda lihat dalam
MSIL
kode tidak diterjemahkan keif
pernyataan, tetapi untukFilters
, danExceptions
tidak dapat dilempar dari dalam area yang ditandai denganFilter 1
danFilter 2
tetapi filter yang melemparException
akan gagal sebagai gantinya, juga nilai perbandingan terakhir didorong ke stack sebelumendfilter
perintah akan menentukan keberhasilan / kegagalan filter (Catch 1
XORCatch 2
akan mengeksekusi sesuai):Juga, secara khusus
Guid
memilikiGuid.TryParse
metode.sumber
Dengan C # 7 jawaban dari Michael Stum dapat ditingkatkan sambil menjaga keterbacaan pernyataan switch:
Dan dengan C # 8 sebagai ekspresi switch:
sumber
when
jauh lebih elegan / sesuai daripada saklar.catch
blok yang berbeda , atau Anda tetap harus melemparkannya .. Dalam pengalaman saya, athrow;
dicatch
blok Anda mungkin bau kode.Jawaban yang diterima tampaknya dapat diterima, kecuali bahwa CodeAnalysis / FxCop akan mengeluh tentang fakta bahwa itu menangkap jenis pengecualian umum.
Juga, tampaknya operator "adalah" mungkin menurunkan kinerja sedikit.
CA1800: Jangan membuang yang tidak perlu kata yang untuk "pertimbangkan menguji hasil dari operator 'sebagai' sebagai gantinya," tetapi jika Anda melakukannya, Anda akan menulis lebih banyak kode daripada jika Anda menangkap setiap pengecualian secara terpisah.
Bagaimanapun, inilah yang akan saya lakukan:
sumber
is
operator mungkin memiliki sedikit dampak negatif pada kinerja, juga benar bahwa pengendali pengecualian bukan tempat yang terlalu khawatir untuk mengoptimalkan kinerja. Jika aplikasi Anda menghabiskan begitu banyak waktu dalam penangan pengecualian sehingga optimasi kinerja di sana akan membuat perbedaan nyata dalam kinerja aplikasi, maka ada masalah kode lain yang perlu diperhatikan. Karena itu, saya masih tidak suka solusi ini karena Anda kehilangan jejak tumpukan dan karena pembersihan secara kontekstual dihapus dari pernyataan tangkapan.is
operator menurunkan kinerja adalah jika Anda kemudian melakukanas
operasi (karenanya mereka memenuhi syarat dengan tidak perlu ). Jika yang Anda lakukan hanyalah menguji gips tanpa benar-benar perlu melakukan gips, makais
operatorlah yang tepat yang ingin Anda gunakan.di C # 6 pendekatan yang disarankan adalah menggunakan Filter Pengecualian, berikut ini sebuah contoh:
sumber
Ini adalah varian dari jawaban Matt (saya merasa ini sedikit lebih bersih) ... gunakan metode:
Pengecualian lain akan dilemparkan dan kode
WebId = Guid.Empty;
tidak akan terkena. Jika Anda tidak ingin pengecualian lain merusak program Anda, tambahkan saja ini SETELAH dua tangkapan lainnya:sumber
WebId = Guid.Emtpy
dalam kasus di mana tidak ada pengecualian dilemparkan.return
jawaban saya. Terima kasih atas masukannya.Jawaban Joseph Daigle adalah solusi yang baik, tetapi saya menemukan struktur berikut menjadi sedikit lebih rapi dan lebih sedikit kesalahan.
Ada beberapa keuntungan dari membalikkan ekspresi:
Ia bahkan dapat dipadatkan menjadi satu baris (meskipun tidak terlalu cantik)
Edit: The penyaringan pengecualian di C # 6.0 akan membuat sintaks sedikit lebih bersih dan dilengkapi dengan sejumlah manfaat lain atas setiap solusi saat ini. (terutama meninggalkan tumpukan tanpa terluka)
Berikut adalah bagaimana masalah yang sama akan terlihat menggunakan sintaks C # 6.0:
sumber
return
, meskipun membalikkan kondisi juga sedikit lebih baik.@Micheal
Versi kode Anda yang sedikit direvisi:
Perbandingan string jelek dan lambat.
sumber
throw new FormatException();
denganthrow new NewlyDerivedFromFormatException();
tanpa melanggar kode menggunakan perpustakaan, dan itu akan berlaku untuk semua kasus penanganan pengecualian kecuali di mana seseorang menggunakan==
bukanis
(atau hanyacatch (FormatException)
).Bagaimana tentang
sumber
sumber
Hati-hati dan Diperingatkan: Jenis fungsional fungsional yang lain.
Apa yang ada di tautan tidak menjawab pertanyaan Anda secara langsung, tetapi sepele untuk memperluasnya agar terlihat seperti:
(Pada dasarnya kosongkan yang lain
Catch
kelebihan yang mengembalikan sendiri)Pertanyaan yang lebih besar adalah mengapa . Saya tidak berpikir biaya melebihi keuntungan di sini :)
sumber
Pembaruan 2015-12-15: Lihat https://stackoverflow.com/a/22864936/1718702 untuk C # 6. Ini lebih bersih dan sekarang standar dalam bahasa.
Diarahkan untuk orang yang menginginkan solusi yang lebih elegan untuk menangkap sekali dan memfilter pengecualian, saya menggunakan metode ekstensi seperti yang ditunjukkan di bawah ini.
Saya sudah memiliki ekstensi ini di perpustakaan saya, awalnya ditulis untuk tujuan lain, tetapi bekerja dengan sempurna untuk
type
memeriksa pengecualian. Plus, imho, itu terlihat lebih bersih daripada banyak||
pernyataan. Juga, tidak seperti jawaban yang diterima, saya lebih suka penanganan eksepsi eksplisit sehinggaex is ...
memiliki perilaku yang tidak diinginkan karena kelas derivasi ditugaskan ke tipe induknya).Pemakaian
Ekstensi IsAnyOf.cs (Lihat Contoh Penanganan Kesalahan Lengkap untuk Ketergantungan)
Contoh Penanganan Kesalahan Lengkap (Salin-Tempel ke aplikasi Konsol baru)
Dua Sampel Unit Tes NUnit
Perilaku mencocokkan untuk
Exception
tipe adalah tepat (mis. Seorang anak BUKAN pasangan yang cocok dengan tipe induknya).sumber
when
, seperti versi apa puncatch (Exception ex) {if (...) {/*handle*/} throw;}
. Nilai sebenarnya dariwhen
adalah bahwa filter berjalan sebelum pengecualian ditangkap , sehingga menghindari korupsi pengeluaran / tumpukan melempar kembali. Ini mengambil keuntungan dari fitur CLR yang sebelumnya hanya dapat diakses oleh VB dan MSIL.IsAnyOf
metode Anda dapat ditulis ulang hanya sebagaip_comparisons.Contains(p_parameter)
Karena saya merasa jawaban-jawaban ini hanya menyentuh permukaan, saya berusaha menggali lebih dalam.
Jadi yang ingin kita lakukan adalah sesuatu yang tidak dapat dikompilasi, katakan:
Alasan kami menginginkan ini adalah karena kami tidak ingin penangan pengecualian menangkap hal-hal yang kami butuhkan nanti dalam proses. Tentu, kita dapat menangkap Pengecualian dan memeriksa dengan 'jika' apa yang harus dilakukan, tapi jujur saja, kita tidak benar-benar menginginkan itu. (FxCop, masalah debugger, keburukan)
Jadi mengapa kode ini tidak dapat dikompilasi - dan bagaimana kita bisa meretasnya sedemikian rupa sehingga akan terjadi?
Jika kita melihat kodenya, yang ingin kita lakukan adalah meneruskan panggilan. Namun, menurut MS Partition II, blok pengendali pengecualian IL tidak akan berfungsi seperti ini, yang dalam hal ini masuk akal karena itu akan menyiratkan bahwa objek 'pengecualian' dapat memiliki tipe yang berbeda.
Atau untuk menuliskannya dalam kode, kami meminta kompiler untuk melakukan sesuatu seperti ini (yah itu tidak sepenuhnya benar, tapi itu adalah hal yang paling dekat yang saya kira):
Alasan bahwa ini tidak akan dikompilasi cukup jelas: apa jenis dan nilai yang akan dimiliki objek '$ exception' (yang ada di sini disimpan dalam variabel 'e')? Cara kami ingin kompiler menangani ini adalah dengan mencatat bahwa tipe dasar umum dari kedua pengecualian adalah 'Pengecualian', menggunakannya untuk variabel yang berisi kedua pengecualian, dan kemudian hanya menangani dua pengecualian yang ditangkap. Cara ini diterapkan di IL adalah sebagai 'filter', yang tersedia di VB.Net.
Untuk membuatnya bekerja dalam C #, kita perlu variabel sementara dengan tipe dasar 'Pengecualian' yang benar. Untuk mengontrol aliran kode, kita dapat menambahkan beberapa cabang. Ini dia:
Kerugian yang jelas untuk ini adalah bahwa kita tidak dapat melempar ulang dengan benar, dan - yah jujur saja - bahwa itu solusi yang jelek. Keburukan dapat diperbaiki sedikit dengan melakukan eliminasi cabang, yang membuat solusinya sedikit lebih baik:
Tinggal menyisakan 'lemparan ulang'. Agar ini berhasil, kita harus dapat melakukan penanganan di dalam blok 'tangkap' - dan satu-satunya cara untuk membuat pekerjaan ini adalah dengan menangkap objek 'Pengecualian'.
Pada titik ini, kita dapat menambahkan fungsi terpisah yang menangani berbagai jenis Pengecualian menggunakan resolusi kelebihan beban, atau untuk menangani Pengecualian. Keduanya memiliki kekurangan. Untuk memulai, inilah cara melakukannya dengan fungsi pembantu:
Dan solusi lainnya adalah menangkap objek Exception dan menanganinya sesuai. Terjemahan paling literal untuk ini, berdasarkan konteks di atas adalah ini:
Jadi untuk menyimpulkan:
sumber
Ini adalah masalah klasik yang dihadapi setiap pengembang C # pada akhirnya.
Biarkan saya membagi pertanyaan Anda menjadi 2 pertanyaan. Pertama,
Bisakah saya menangkap beberapa pengecualian sekaligus?
Singkatnya, tidak.
Yang mengarah pada pertanyaan selanjutnya,
Bagaimana cara saya menghindari menulis kode duplikat mengingat saya tidak bisa menangkap beberapa tipe pengecualian di blok catch () yang sama?
Mengingat sampel spesifik Anda, di mana nilai kembali lebih murah untuk dibangun, saya suka mengikuti langkah-langkah ini:
Jadi kodenya terlihat seperti:
Jika ada pengecualian yang dilemparkan, maka WebID tidak pernah diatur ke nilai setengah dibangun, dan tetap Guid.Empty.
Jika membangun kembali nilai itu mahal, dan mengatur ulang nilai jauh lebih murah, maka saya akan memindahkan kode reset ke fungsinya sendiri:
sumber
Jadi, Anda mengulang banyak kode dalam setiap pengecualian-switch? Kedengarannya seperti mengekstraksi metode akan menjadi ide dewa, bukan?
Jadi kode Anda sampai seperti ini:
Saya heran mengapa tidak ada yang memperhatikan duplikasi kode itu.
Dari C # 6 Anda selanjutnya memiliki filter pengecualian seperti yang telah disebutkan oleh orang lain. Jadi, Anda dapat mengubah kode di atas menjadi ini:
sumber
Ingin menambahkan jawaban singkat saya ke utas yang sudah lama ini. Sesuatu yang belum disebutkan adalah urutan prioritas pernyataan penangkapan, lebih khusus Anda perlu mengetahui ruang lingkup setiap jenis pengecualian yang Anda coba tangkap.
Sebagai contoh jika Anda menggunakan pengecualian "tangkap semua" sebagai Pengecualian, itu akan mendahului semua pernyataan tangkap lainnya dan Anda jelas akan mendapatkan kesalahan penyusun namun jika Anda membalik urutan, Anda dapat menyusun pernyataan tangkap Anda (sedikit anti-pola yang saya pikir ) Anda dapat meletakkan catch-all type Exception di bagian bawah dan ini akan menangkap setiap pengecualian yang tidak sesuai dengan yang lebih tinggi dalam percobaan Anda .. blok tangkapan:
Saya sangat merekomendasikan orang-orang meninjau dokumen MSDN ini:
Hirarki Pengecualian
sumber
Mungkin mencoba untuk menjaga kode Anda sederhana seperti menempatkan kode umum dalam suatu metode, seperti yang akan Anda lakukan di bagian lain dari kode yang tidak ada dalam klausa catch?
Misalnya:
Betapa saya akan melakukannya, berusaha menemukan yang sederhana adalah pola yang indah
sumber
Perhatikan bahwa saya memang menemukan satu cara untuk melakukannya, tetapi ini lebih mirip bahan untuk The Daily WTF :
sumber
Perlu disebutkan di sini. Anda dapat menanggapi beberapa kombinasi (Kesalahan pengecualian dan pengecualian. Pesan).
Saya mengalami skenario penggunaan kasus ketika mencoba untuk melemparkan objek kontrol dalam datagrid, dengan konten sebagai TextBox, TextBlock atau CheckBox. Dalam hal ini Pengecualian yang dikembalikan adalah sama, tetapi pesannya beragam.
sumber
Saya ingin menyarankan jawaban terpendek (satu lagi gaya fungsional ):
Untuk ini, Anda perlu membuat beberapa metode "Catch" overload, mirip dengan System.Action:
dan seterusnya sebanyak yang Anda inginkan. Tetapi Anda perlu melakukannya sekali dan Anda dapat menggunakannya di semua proyek Anda (atau, jika Anda membuat paket nuget, kami juga bisa menggunakannya).
Dan implementasi CatchMany:
ps Saya belum menaruh cek nol untuk kesederhanaan kode, pertimbangkan untuk menambahkan validasi parameter.
ps2 Jika Anda ingin mengembalikan nilai dari tangkapan, perlu melakukan metode Penangkapan yang sama, tetapi dengan pengembalian dan Fungsi alih-alih Tindakan dalam parameter.
sumber
Panggil saja coba dan tangkap dua kali.
Sederhana saja !!
sumber
Dalam c # 6.0, Filter Pengecualian adalah peningkatan untuk penanganan pengecualian
sumber
catch (HttpException e) when e.GetHttpCode() == 400 { WriteLine("Bad Request"; }