Porque a especificação da linguagem espera uma expressão do tipo System.Exception
lá (portanto, null
é válida nesse contexto) e não restringe essa expressão a ser não nula. Em geral, não há como detectar se o valor dessa expressão é null
ou não. Teria de resolver o problema da parada. O tempo de execução terá que lidar com o null
caso de qualquer maneira. Vejo:
Exception ex = null;
if (conditionThatDependsOnSomeInput)
ex = new Exception();
throw ex;
Eles poderiam, é claro, fazer o caso específico de jogar o null
literal inválido, mas isso não ajudaria muito, então por que desperdiçar espaço de especificação e reduzir a consistência para obter poucos benefícios?
Isenção de responsabilidade (antes de eu levar um tapa de Eric Lippert): Esta é minha própria especulação sobre o raciocínio por trás dessa decisão de design. Claro, eu não estive na reunião de design;)
A resposta à sua segunda pergunta, se uma variável de expressão capturada dentro de uma cláusula catch pode ser nula: Embora a especificação C # não diga se outras linguagens podem causar null
a propagação de uma exceção, ela define a maneira como as exceções são propagadas:
As cláusulas catch, se houver, são examinadas em ordem de aparecimento para localizar um manipulador adequado para a exceção. A primeira cláusula catch que especifica o tipo de exceção ou um tipo base do tipo de exceção é considerada uma correspondência. Uma cláusula catch geral é considerada uma correspondência para qualquer tipo de exceção. [...]
Pois null
, a afirmação em negrito é falsa. Portanto, embora seja puramente baseado no que a especificação do C # diz, não podemos dizer que o tempo de execução subjacente nunca lançará nulo, podemos ter certeza de que, mesmo se for esse o caso, ele será tratado apenas pela catch {}
cláusula genérica .
Para implementações C # na CLI, podemos consultar a especificação ECMA 335. Esse documento define todas as exceções que a CLI lança internamente (nenhuma das quais são null
) e menciona que os objetos de exceção definidos pelo usuário são lançados pela throw
instrução. A descrição dessa instrução é virtualmente idêntica à throw
instrução C # (exceto que não restringe o tipo do objeto a System.Exception
):
Descrição:
A throw
instrução lança o objeto de exceção (tipo O
) na pilha e esvazia a pilha. Para obter detalhes sobre o mecanismo de exceção, consulte a Partição I.
[Nota: Enquanto o CLI permite que qualquer objeto seja lançado, o CLS descreve uma classe de exceção específica que deve ser usada para interoperabilidade de linguagem. nota final]
Exceções:
System.NullReferenceException
é lançado se obj
for null
.
Correção:
O CIL correto garante que o objeto seja sempre null
ou uma referência de objeto (ou seja, do tipo O
).
Acredito que isso seja suficiente para concluir que as exceções detectadas nunca são null
.