Since the language specification expects an expression of type System.Exception (therefore null is valid in this context) and does not limit this expression to non-zero. In general, there is no way to determine if the value of this expression is null or not. This would solve the problem of termination. In any case, the runtime will deal with the null event. Cm:
Exception ex = null; if (conditionThatDependsOnSomeInput) ex = new Exception(); throw ex;
They could, of course, make the specific case of throwing the null literal invalid, but that would not help, so why waste the specification space and reduce consistency for a small gain?
Disclaimer (before Eric Lippert hits me): This is my own assumption about the reasoning behind this design decision. Of course, I was not at a design meeting;)
The answer to your second question: can the expression variable that gets into the catch clause be null: although the C # specification does not say whether other languages ββcan throw a null exception, it determines how the exceptions are propagated:
Catch clauses, if any, are examined in order of appearance to find a suitable exception handler. The first catch clause , which indicates the type of exception or the base type of the type of exception , is considered a match. The general catch clause is considered a match for any type of exception. [...]
For null bold operator is false. Thus, although it is purely based on what the C # specification says, we cannot say that the underlying runtime will never show zero, we can be sure that even if this happens, it will only be handled by the common catch {} clause .
To implement C # in the CLI, we can refer to the ECMA 335 specification. This document defines all the exceptions that the CLI throws inside (none of which is null ), and mentions that custom exception objects are thrown by the throw command. The description of this instruction is almost identical to the C # throw operator (except that it does not limit the type of the System.Exception object):
Description:
The throw command throw an exception object (type O ) onto the stack and frees the stack. For more information on the exclusion mechanism, see Section I.
[Note. Although the CLI allows any object to be thrown, the CLS describes a specific exception class that should be used for language interaction. end note]
Exceptions:
System.NullReferenceException is System.NullReferenceException if obj null .
Correctness:
A valid CIL ensures that the object is always either null or a reference to the object (i.e., type O ).
I believe that there are enough of them to make caught exceptions, never null .