Поскольку спецификация языка ожидает там выражения типа 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
.