Поскольку спецификация языка ожидает там выражения типа System.Exception(следовательно, nullявляется допустимым в этом контексте) и не ограничивает это выражение ненулевым значением. В общем, невозможно определить, равно ли значение этого выражения null. Это должно было бы решить проблему остановки. Среда выполнения в nullлюбом случае должна будет заняться этим делом. Видеть:
Exception ex = null;
if (conditionThatDependsOnSomeInput)
ex = new Exception();
throw ex;
Они, конечно, могли бы сделать конкретный случай исключения nullбуквального недопустимым, но это не сильно помогло бы, так зачем тратить пространство спецификации и уменьшать согласованность с небольшой выгодой?
Заявление об ограничении ответственности (до того, как меня ударит Эрик Липперт): это мое собственное предположение о причинах этого дизайнерского решения. Я, конечно, не был на дизайнерской встрече;)
Ответ на ваш второй вопрос, может ли переменная выражения, пойманная в предложении catch, когда-либо иметь значение NULL: хотя спецификация C # nullничего не говорит о том, могут ли другие языки вызывать распространение исключения, она определяет способ распространения исключений:
Предложения catch, если таковые имеются, проверяются в порядке появления, чтобы найти подходящий обработчик исключения. Первое предложение catch , определяющее тип исключения или базовый тип типа исключения, считается совпадением. Общее предложение catch считается подходящим для любого типа исключения. [...]
Ибо nullжирное заявление неверно. Итак, хотя чисто на основе того, что говорится в спецификации C #, мы не можем сказать, что базовая среда выполнения никогда не будет генерировать null, мы можем быть уверены, что даже в этом случае это будет обрабатываться только общим catch {}предложением.
Для реализации C # в CLI мы можем обратиться к спецификации ECMA 335. Этот документ определяет все исключения, которые CLI генерирует внутренне (ни одно из которых не является null), и упоминает, что определенные пользователем объекты исключения генерируются throwинструкцией. Описание этой инструкции практически идентично инструкции C # throw(за исключением того, что она не ограничивает тип объекта System.Exception):
Описание:
throwИнструкция бросает объект исключения (типа O) в стеке и опустошает стек. Для получения подробной информации о механизме исключений см. Раздел I.
[Примечание: CLI разрешает генерирование любого объекта, CLS описывает конкретный класс исключения, который должен использоваться для языковой совместимости. конец примечания]
Исключения:
System.NullReferenceExceptionвыбрасывается, если objесть null.
Правильность:
Правильный CIL гарантирует, что объект всегда является либо nullссылкой на объект (т. Е. Типом O).
Я считаю, что этого достаточно, чтобы сделать вывод, что пойманных исключений никогда не бывает null.