Why does C # allow you to throw zero?

When writing particularly sophisticated exception handling code, someone asked if you need to make sure that your exception object is not zero? And I said, of course not, but then I decided to try. Apparently, you can throw zero, but it still turns into an exception.

Why is this allowed?

throw null; 

In this snippet, fortunately, ex is not null, but can it ever be?

 try { throw null; } catch (Exception ex) { //can ex ever be null? //thankfully, it isn't null, but is //ex is System.NullReferenceException } 
+62
c # exception-handling
03 Feb '10 at 21:54
source share
7 answers

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 .

+67
Feb 03 '10 at 21:56
source share

You can apparently throw zero, but it still turns into an exception.

Attempting to throw a null object results in a (completely unbound) Null Reference Exception.

The question of why you are allowed to throw null is the question of why you can do this:

 object o = null; o.ToString(); 
+21
Feb 03 '10 at 21:56
source share

While it is not possible to reset null in C # because the throw will detect this and turn it into a NullReferenceException, it is possible to get null ... I am getting it right now, which causes my catch (which did not expect the "ex" to be null ) to get a null reference exception, which then causes my application to die (since that was the last catch).

So, although we can't throw null from C #, netherworld can throw null, so your Exception ex is better prepared to receive it. Just FYI.

+5
Sep 28 '11 at 7:18
source share

Taken from here :

If you use this expression in your C # code it will be a NullReferenceException. That is, because request-request requires an object of type Exception as its only parameter. But this object is null in my example.

+4
Feb 03 '10 at 21:57
source share

I think maybe you can’t - when you try to throw zero, it cannot, so it does what it should in case of an error in which an exception with a null reference is thrown. That way, you are not actually throwing zero, you cannot throw zero, which results in a throw.

+2
Feb 03 '10 at 21:57
source share

Trying to answer: ".." ex "is not null, but can it ever be?":

Since we may not be able to throw exceptions that are null, the catch clause should also never catch an exception that is null. So ex can never be null.

Now I see that this question has already been asked .

+2
Feb 03 2018-10-02T00
source share

Remember that the exception contains information about where the exception is generated. Seeing that the constructor has no idea where to throw it, then it only makes sense that the throw method introduces these details into the object at the throw point. In other words, the CLR attempts to enter data in null, which raises a NullReferenceException.

Not sure if this is exactly what is happening, but explains this phenomenon.

Assuming this is true (and I cannot think that a better way to make ex be null than throw null;), this means that ex cannot be null.

+1
03 Feb '10 at 22:27
source share



All Articles