C# throw oddity

  • Thread starter Thread starter Mike Schilling
  • Start date Start date
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.
 
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.
 
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
 
Back
Top