Chciałbym wyłapać wszystkie warianty ogólnej klasy wyjątków i zastanawiałem się, czy można to zrobić bez wielu bloków wyłapywania. Powiedzmy na przykład, że mam klasę wyjątków:
public class MyException<T> : Exception
{
public string MyProperty { get; }
public MyException(T prop) : base(prop.ToString())
{
MyProperty = prop?.ToString();
}
}
oraz dwie klasy pochodne:
public class MyDerivedStringException : MyException<string>
{
public MyDerivedStringException(string prop) : base(prop)
{
}
}
public class MyDerivedIntException : MyException<int>
{
public MyDerivedIntException(int prop) : base(prop)
{
}
}
jest sposób na złapanie obu MyDerivedStringException
i MyDerivedIntException
jednego bloku połowu.
Próbowałem tego:
try
{
...
}
catch(Exception e) when (e is MyDerivedStringException || e is MyDerivedIntException)
{
}
ale nie jest bardzo czysty i oznacza, że nie mam dostępu MyProperty
.
Interesuje mnie ogólne rozwiązanie problemu, ale w moim przypadku ogólny wyjątek jest zdefiniowany w bibliotece strony trzeciej, która, jak wskazano poniżej, wprowadza dodatkowe ograniczenia dla problemu.
Exception
iMyException<T>
byłaby w porządku.Test, jeśli twoja
Type
pochodna pochodzi od ogólnej, to:Ale dotyczy to tylko samych typów pochodnych, takich jak
MyException<int>
lubMyException<string>
.Jeśli masz inne pochodne, takie jak
MyDerivedStringException
musiałeś przetestować:Działa to w przypadku każdego istniejącego rodzaju ogólnego, ale musisz znać poziom dziedziczenia dla tego testu lub przejść przez wszystkie typy podstawowe.
Więc możesz to zrobić:
źródło
Ta implementacja wykonuje i rozpakowuje, jeśli T: Wartość to Typ wartości ... ale w odniesieniu do wykorzystania można kontrolować wpływ na wydajność za pomocą liczby prób uruchomienia / rozpakowania.
Logika
źródło
Niestety nie możesz złapać
catch(MyException ex)
klasa, ponieważ oczekuje typu.Najlepszym rozwiązaniem byłoby utworzenie klasy podstawowej lub interfejsu, złapanie go i stamtąd typ.
Jest już odpowiedź na tak oto , w jaki sposób uzyskać typ i to zrobić.
źródło
ta implementacja oddziela delegata obsługi dla typu wyjątku od kontekstu T / C ... Może to być trochę zbyt ryzykowne, ale fajne jest to, że możesz wstrzykiwać różne procedury obsługi w zależności od zakresu ponownego użycia i kontekstu wykorzystanie.
logika rejestracji
źródło