Throwing an exception from some locations are unexpected and can cause problems. For example when you call an exception from inside a finalizer, the CLR will stop executing the finalizer, and pass the exception to the base class finalizer (if any). If there is no base class, then the finalizer is discarded.
Do not throw exceptions from the following locations:
Location | Note |
Event accessor methods | The followings exceptions are allowed: System.InvalidOperationException, System.NotSupportedException and System.ArgumentException. This also includes their derivates. |
Equals methods | An Equals method should return true or false. Return false instead of an exception if the arguments to not match. |
GetHashCode() methods | GetHashCode() should always return a value, otherwise you lose values in a hash table. |
ToString methods | This method is also used by the debugger to display information about objects in a string format. Therefore it should not raise an exception. |
Static constructors | A type becomes unusable if an exception is thrown from its static constructor. |
Finalizers (finalizers) | Throwing an exception from a finalizer can cause a process to crash. |
Dispose methods | Dispose methods are often called in finally clauses as part of cleanup. Also Dispose(false) is called from a finalizer, which in itself should not throw an exception als. |
Equality Operators (== , != ) | Like the Equals methods, the operators should always return true or false. |
Implicit cast operators | A user is usually unaware that an implicit cast operators is called, therefore throwing an exception from them is unexpected and should not be done. |
Exception constructor | Calling a exception constructor is done to throw an exception. If the constructor throws an exception, then this is confusing. |