throw : If we use "throw" statement, it preserve original error stack information. In exception handling "throw" with empty parameter is also called re-throwing the last exception.

throw ex : If we use "throw ex" statement, stack trace of exception will be replaced with a stack trace starting at the re-throw point. It is used to intentionally hide stack trace information.
  1. catch (Exception ex)
  2. {
  3. // do some stuff here
  4. throw; // a) continue ex
  5. throw new MyException("failed", ex); // b) wrap
  6. throw new MyException("failed"); // c) replace
  7. throw ex; // d) reset stack-trace
  8. }
So it is good practice to use the "throw" statement, rather than "throw ex" because it will give us more accurate stack information rather than "throw ex".