'throw e;' vs. 'throw;'

Someone asked what the practical differences are between 'throw;' (no arguments) and 'throw object;'   (in C# syntax).

Specifically, what's the difference between:

 
        catch (Exception e)
        {
            throw;
        }

and

         catch (Exception e)
        {
            throw e;
        }

This is mildly related to the 'catch' vs 'catch(Exception e)' vs. 'catch  (SomeSpecificException e)'. I'll avoid talking about catch, and just focus on the rethrow.

What's the same:

  1. Both throw an exception.

  2. Both have the same debuggability problems associated with catch / rethrow.

  3. They can be called in the same way.  I used code like:

             catch (Exception e)
            {            
                if (...) 
                    throw;
                else
                    throw e;
            }
    

    as an academic way to demonstrate that they must have some similar properties. Never actually write code like that!

  4. They can both be used in a naked catch block, although as difference #1 below mentions, 'throw e'; can't be used to rethrow the current exception.

         catch
        {
            throw new MyWrapperException();
        }

What's different:

  1. 'throw;' can only be used in the lexical scope of a catch block since it must gaurantee having a current exception. 'throw e' can be used anywhere.
  2. 'throw e' lets you provide a new exception object, such as a wrapper around the original exception.
  3. Only 'throw' can be used to rethrow the current exception within a naked catch block
  4. They both rethrow the current exception object, but “throw e;” resets parameters on it like the Exception.StackWalk property.
  5. They generate different IL opcodes. C#'s 'throw;' compiles to the 'rethrow' IL opcode, which doesn't take any parameters on the IL stack. 'throw e;' compiles to the 'throw' IL opcode, which takes 1 IL stack parameter: the exception to throw.
     

Check out the C# spec for more details