В VB можно ловить интерфейсы, используя что-то вроде:
' Doesn't require external function, but will will require typecast
' if it needs to actually use Ex as IMyExceptionInterface
Catch Ex As Exception When TypeOf(Ex) Is IMyExceptionInterface
' Alternate form: requires pre-declared variable and a function:
' Function TryCastIntoSecondParam(Of TSource As Class, TDest As Class) _
' (ByVal Thing As TSource, ByRef Dest As TDest)
' Dim Result As TDest
' Result = TryCast(Thing, TDest)
' Dest = Result
' Return Dest IsNot Nothing
' End Function
Catch Ex As Exception When TryCastIntoSecondParam(Ex, myIMyException)
Если разработчики компилятора VB или C # хотят сделать это, они могут позволить использовать синтаксис
Catch Ex As IMyExceptionInterface ' vb
catch IExceptionInterface ex ' C#
и реализуйте его с помощью приведенного выше кода. Даже без поддержки компилятора пользователи vb могут получить правильную семантику с помощью приведенного выше кода. В C # необходимо было бы перехватить исключение, проверить, является ли это желаемый тип, и повторно вызвать, если это не так; семантика этого отличается от семантики использования фильтра, чтобы избежать перехвата исключения в первую очередь. Обратите внимание, что для того, чтобы компилятор C # реализовывал вышеупомянутые конструкции, он должен был бы использовать блоки фильтров, но он не должен был бы раскрывать всю мощь блоков фильтров программистам - то, что разработчики C # сознательно отказались делать.
Все, что было сказано, я подозреваю, что ответ на первоначальный вопрос может быть следующим: «дизайнеры не могли придумать ни одного хорошего варианта использования для такой вещи», или это может быть «Интерфейсы требуют более сложного разрешения типов, чем классы, создавая возможность того, что простое действие принятия решения о том, следует ли ловить исключение, может потерпеть неудачу за исключением своего собственного. "
На самом деле, мне не нравится использование типов классов в качестве средства решения, какие исключения отлавливать, поскольку вопрос о том, отлавливать ли исключение, часто в значительной степени ортогональн к вопросу о том, что именно произошло, вызвавшее его. Если попытка загрузить документ не удалась, меня почти не интересует вопрос о том, был ли какой-либо аргумент вне допустимого диапазона, или какой-либо индекс вышел за пределы допустимого диапазона, поскольку меня интересует, могу ли я безопасно восстановиться после попытки притворяясь, что я никогда этого не сделал. Что действительно необходимо, так это мера «серьезности» для исключений, которая может увеличиваться или уменьшаться по мере того, как исключение всплывает в цепочке вызовов. Такая вещь может быть несколько практичной в vb.net (которая имеет фильтры исключений), но, вероятно, не в C # (который не имеет), но в любом случае будет ограничена отсутствием какой-либо поддержки во встроенных исключениях.
Редактировать / Добавление
Можно использовать фильтры исключений в проекте C #, если кто-либо использует DLL, написанную в vb, для реализации оболочки try / filter / catch / finally, которая вызывает некоторые делегаты. К сожалению, использование такой DLL потребует некоторых компромиссов между эффективностью выполнения и удобочитаемостью кода. Я не думал о реализации такой DLL для конкретной оптимизированной цели - перехватить произвольное количество интерфейсов; Я не знаю, будет ли какое-либо преимущество в том, чтобы включать такую функциональность в DLL, вместо того, чтобы передавать ей лямбда-выражение или анонимный метод, чтобы проверить, должно ли быть поймано исключение.
Кстати, еще одна функция, которую может предоставить оболочка, которая в C # отсутствует, - это возможность сообщать о состоянии двойной ошибки (исключение происходит в основной линии, а другое исключение возникает во время последующего блока finally) без необходимости поймать начальное исключение. Когда исключение возникает в блоке finally, это, как правило, более серьезная проблема, чем исключение, которое возникает в основной строке, и поэтому его не следует подавлять, но если исключение «окончательного блока» просачивается вверх по стеку вызовов, как правило, уничтожаются любые доказательства. оригинального исключения. Хотя окружающий код, скорее всего, будет более заинтересован в сбое очистки, чем исходное исключение, регистрация обоих исключений может оказаться гораздо более полезной, чем удушение оригинала.