C# throw oddity

M

Mike Schilling

These two fragments do not act identically:

(1)
catch(Exception ex)
{
...
throw ex;
}

(2)
catch (Exception ex)
{
...
throw;
}

In (1), ex.StackTrace is reinitialized, so the exception will appear to have
originated inside the fragment. That is, the MSIL throw instruction is
generated.

In (2) ex.StackTrace is not reinitialized, so the exception will appear to
have originated wherever it was last thrown. That is, the MSIL rethrow
instruction is generated.

I couldn't find any place this is documented.
 
J

Jon Skeet

Mike Schilling said:
These two fragments do not act identically:

<snip>

Indeed they don't.
I couldn't find any place this is documented.

No - it's not in the spec as far as I can see. Indeed, I'd go so far as
to say that the spec *implies* that they should do the same thing. From
section 15.9.5 (ECMA):

<quote>
A throw statement with an expression throws the value produced by
evaluating the expression. The expression must denote a value of the
class type System.Exception or of a class type that derives from
System.Exception. If evaluation of the expression produces null, a
System.NullReferenceException is thrown instead.

A throw statement with no expression can be used only in a catch block,
in which case, that statement re-throws the exception that is currently
being handled by that catch block.
</quote>

I suppose there's a difference between "re-throws" and "throws", but
it's a bit tricksy. I think it should at the very least suggest that
there *can* be a difference, and perhaps give an informational note
giving an example of what the difference is in the MS CLR.
 
F

Fergus Cooney

Hi Mike, Jon,

<quote>
A throw statement with an expression THROWS the value produced by
evaluating the expression. The expression must denote a value of the
class type System.Exception or of a class type that derives from
System.Exception. If evaluation of the expression produces null, a
System.NullReferenceException is thrown instead.

A throw statement with no expression can be used only in a catch
block,
in which case, that statement RE-throws the exception that is
currently
being handled by that catch block.
</quote>

If I'd read that before reading Mike's post (thanks Mike, learned
something new there), I'd probably have missed the sublety or assumed
a typo or something. Having read Mike's post <first>, it makes perfect
sense.

I think they should introduce a new keyword, "rethrow", to make it
explicit.

Regards,
Fergus
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top