CLS является более строгим, чем CLR, что позволит вам бросать и ловить любые типы объектов (даже типы значений). Зачем?
Кроме того, что произойдет, если некоторый не совместимый с CLS код бросит объект, не являющийся производным от исключения, при вызове кодом, совместимым с CLS?
ОБНОВИТЬ
На второй вопрос ответил @Marton. Все еще удивляюсь почему.
CLS определяет минимальный набор языковых функций, необходимых многим приложениям таким образом, что если API использует только эти функции, он может использоваться любым CLS-совместимым языком. Поэтому, естественно, это более ограничительно, чем CLR. С другой стороны, CLR предназначен для обработки управляемого кода с любого CLI-совместимого языка.
Пример языка, который позволяет генерировать не-CLS-совместимые исключения (те, которые не являются производными от System.Exception) является C ++ / CLI. Этот язык был разработан, чтобы быть надмножеством простого C ++, который включает в себя возможность генерировать исключения любого типа. Это может быть единственной веской причиной для исключения не-CLS.
По поводу второго вопроса. Исключение, не относящееся к CLS, при выдаче в разных случаях происходят разные вещи:
В CLR 2.0 и более поздних версиях CLR внутренне всегда помещает исключение в System.Runtime.CompilerServices.RuntimeWrappedException который поддерживает поле типа объект который ссылается на оригинальное исключение. Это позволяет записывать трассировку стека. Когда он распространяется вверх по стеку:
Если System.Runtime.CompilerServices.RuntimeCompatibilityAttribute атрибут был применен к сборке функции, в которой CLR ищет соответствующий блок catch и WrapNonExceptionThrows установите значение true (автоматически применяется компиляторами Visual C # и Basic), затем исключение продолжает переноситься.
В противном случае, если атрибут не был применен или если WrapNonExceptionThrows было установлено в false, исключение разворачивается каждый раз, когда блок catch проверяется на соответствие.
редактировать
В C # в первом вышеупомянутом пункте и во втором случае второго маркера единственный способ отловить исключение, не относящееся к CLS, — это использовать блок перехвата без параметров.
Часть почему я не могу ответить, но вторая часть я могу:
что произойдет, если какой-нибудь не совместимый с CLS код выдаст исключение
производный объект при вызове с помощью CLS-совместимого кода?
Если вы бросите объект, не являющийся производным от исключения, он все равно будет перехвачен CLS-совместимым кодом, поскольку он будет заключен в RuntimeWrappedException
,
(The исходная статья стоит прочитать для более подробной информации.)