Существуют некоторые семантические различия между перехватом и повторным созданием исключения, а не его перехватом. Фильтры исключений поэтому очень полезны, так как они позволяют, например, Msgstr "Поймать Ex как исключение, когда IsNiceException (Ex)". К сожалению, единственный способ использовать их в программе на C # - это использовать DLL, чтобы обернуть необходимую функциональность (сама DLL может быть написана на vb или другом языке). Типичный шаблон может быть что-то вроде:
TryWhenCatchFinally(
() => {trycode;},
(Exception ex) => {codeWhichReturnsTrueForExceptionsWorthCatching;},
(Exception ex) => {codeToHandleException;},
(ExceptionStatus status, Exception ex) => {finallyCode;});
Параметр ExceptionStatus для кода "finally" будет перечислением, указывающим, было ли (1) исключение не произошло, (2) исключение произошло, но было обработано, (3) произошло исключение и было обработано, но другое исключение было выдается или (4) возникла исключительная ситуация, но CodeWhichReturnsTrueForExceptionsWorthCatching вернул false; (5) возникла исключительная ситуация, которая не была обработана в trycode и не обработана этим блоком, но trycode завершился в любом случае (редкая ситуация, но есть способы, которыми это может произойти). Параметр Ex будет нулевым в первом случае и будет содержать соответствующее исключение в других - потенциально полезную информацию, которая будет иметься, если во время обработки блока finally возникает исключение (подавление исключения, возникающего в блоке finally, может быть плохим, но если более раннее исключение не регистрируется или теряется до того, как новое исключение исчезнет, все данные из более раннего исключения, как правило, будут потеряны: если то же условие, которое вызвало более раннее исключение, вызвало более позднее, более раннее исключение может иметь более полезную информацию о том, что произошло неправильно).
Кстати, несколько заметок с этим шаблоном:
- Код, который решает, поймать ли исключение, будет запущен до выполнения вложенных блоков finally; он может собирать полезные данные для регистрации (тот факт, что блоки finally не запускаются, может сделать доступной для регистрации информацию, которая может быть уничтожена вложенными блоками finally), но фактическая очистка обычно должна выполняться после запуска блоков finally.
- В настоящее время кажется, что исключения, которые могли бы выйти из фильтров, были подавлены, но я не уверен, что поведение гарантировано. Операции, которые могут привести к утечке исключений, вероятно, не должны выполняться внутри фильтров.
- Если «trycode» содержит блок try-finally, который вложен в блок try-catch, исключение, которое возникает в части «try» этого блока try-finally, не обрабатывается TryCatchWhenFamily и не является вложенной областью действия, но обрабатывается внешним блоком, и обработка внутреннего блока try-finally вызывает исключение, которое обрабатывает внутренний блок try-catch, исключение, которое, как решил внешний блок, он собирался перехватить, может исчезнуть без возможности быть пойманным. Если метод TryWhenCatchFinally закодирован для обнаружения этого условия, он может сообщить об этом своему блоку кода finally (блок finally может или не может захотеть что-либо сделать с этим условием, но, вероятно, его следует как минимум зарегистрировать).