Я хотел бы поймать все варианты универсального класса исключений, и мне было интересно, есть ли способ сделать это без нескольких блоков catch. Например, скажем, у меня есть класс исключения:
public class MyException<T> : Exception
{
public string MyProperty { get; }
public MyException(T prop) : base(prop.ToString())
{
MyProperty = prop?.ToString();
}
}
и два производных класса:
public class MyDerivedStringException : MyException<string>
{
public MyDerivedStringException(string prop) : base(prop)
{
}
}
public class MyDerivedIntException : MyException<int>
{
public MyDerivedIntException(int prop) : base(prop)
{
}
}
Есть ли способ поймать MyDerivedStringException
и MyDerivedIntException
в одном и том же блоке?
Я пробовал это:
try
{
...
}
catch(Exception e) when (e is MyDerivedStringException || e is MyDerivedIntException)
{
}
но это не очень чисто и означает, что у меня нет доступа к MyProperty
.
Меня интересует общее решение проблемы, но в моем случае общее исключение определено в сторонней библиотеке, которая, как указано ниже, добавляет некоторые дополнительные ограничения к проблеме.
Exception
иMyException<T>
все будет в порядке.Тест, если ваш
Type
получен из универсального:Но это верно только для самих производных типов, таких как
MyException<int>
илиMyException<string>
.Если у вас есть дополнительные производные, как
MyDerivedStringException
вы должны были проверить:Так что это работает для любого существующего генерика, но вам нужно знать уровень наследования для этого теста или пройтись по всем базовым типам.
Так что вы можете сделать это:
источник
Эта реализация блокирует и распаковывает, если T: Value имеет значение Valuetype ... но в отношении использования вы можете контролировать влияние на производительность с количеством попыток блокировать / распаковывать.
логика
источник
К сожалению, вы не можете поймать с
catch(MyException ex)
класс, как и ожидается тип.Лучше всего было бы создать базовый класс или интерфейс, поймать его и получить тип оттуда.
Существует уже ответ на так вот о том , как получить тип и сделать это.
источник
эта реализация абстрагирует делегат обработки для типа исключения от контекста T / C ... Это может быть немного слишком авантюрно, но крутая часть в том, что вы можете вводить различные обработчики в зависимости от области повторного использования и контекста использование.
логика регистрации
источник