Saya ingin menangkap semua varian dari kelas pengecualian umum dan saya bertanya-tanya apakah ada cara untuk melakukannya tanpa beberapa blok penangkap. Sebagai contoh katakanlah saya memiliki kelas pengecualian:
public class MyException<T> : Exception
{
public string MyProperty { get; }
public MyException(T prop) : base(prop.ToString())
{
MyProperty = prop?.ToString();
}
}
dan dua kelas turunan:
public class MyDerivedStringException : MyException<string>
{
public MyDerivedStringException(string prop) : base(prop)
{
}
}
public class MyDerivedIntException : MyException<int>
{
public MyDerivedIntException(int prop) : base(prop)
{
}
}
apakah ada cara menangkap keduanya MyDerivedStringException
dan MyDerivedIntException
dalam satu blok tangkapan.
Saya sudah mencoba ini:
try
{
...
}
catch(Exception e) when (e is MyDerivedStringException || e is MyDerivedIntException)
{
}
tetapi tidak sangat bersih dan berarti saya tidak memiliki akses ke MyProperty
.
Saya tertarik pada solusi umum untuk masalah ini, tetapi dalam kasus saya, Pengecualian generik didefinisikan di perpustakaan pihak ketiga yang sebagaimana ditunjukkan di bawah ini menambahkan beberapa kendala tambahan untuk masalah tersebut.
Exception
danMyException<T>
akan baik-baik saja.Tes jika Anda
Type
berasal dari generik adalah:Tetapi ini hanya berlaku untuk tipe turunan itu sendiri, seperti
MyException<int>
atauMyException<string>
.Jika Anda memiliki turunan lebih lanjut seperti
MyDerivedStringException
Anda harus menguji pada:Jadi ini berfungsi untuk semua generik yang ada, tetapi Anda perlu mengetahui tingkat pewarisan untuk tes ini, atau mengulangi semua tipe dasar.
Jadi Anda bisa melakukan ini:
sumber
Ini kotak implementasi dan unboxes jika T: Value is Valuetype ... tetapi sehubungan dengan pemanfaatan Anda dapat mengontrol implikasi kinerja dengan berapa kali Anda mencoba untuk box / unbox.
Logika
sumber
Sayangnya, Anda tidak dapat menangkap dengan
catch(MyException ex)
kelas, karena mengharapkan suatu tipe.Taruhan terbaik Anda adalah membuat kelas dasar atau antarmuka, menangkapnya dan mendapatkan jenisnya dari sana.
Sudah ada jawaban jadi di sini tentang cara mendapatkan jenis dan melakukan ini.
sumber
implementasi ini mengabstraksi delegasi penanganan untuk tipe pengecualian jauh dari konteks T / C ... Ini mungkin agak terlalu berani, tetapi bagian kerennya adalah Anda dapat menyuntikkan penangan yang berbeda tergantung pada cakupan penggunaan kembali dan konteks pemanfaatan.
logika pendaftaran
sumber