Throwing a general exception type such as System.Exception or System.SystemException in a library or Framework forces consumers to catch all exceptions, including unknown exceptions that they do not know how to handle (see FAQ: Why does FxCop warn against catch(Exception)? for reasons as to why this is bad).

Instead, either throw a more derived type that already exists in the Framework, or create your own type that derives from Exception.

The following list examples of when you should throw specific exceptions:

When validating a parameter (including the value parameter in the set accessor of a property) that:

is a null reference (Nothing in Visual Basic) 
    throw System.ArgumentNullException

is outside of the allowable range of values (such as an index for a Collection/List)
    throw System.ArgumentOutOfRangeException (DO NOT throw System.IndexOutOfRangeException)

is outside the allowable values for a enum
    throw System.ComponentModel.InvalidEnumArgumentException

contains a format that not meet the parameter specifications of a method (such as the format string for ToString(String))
    throw System.FormatException

is otherwise invalid (such as an empty string)
    throw System.ArgumentException

When an operation is invalid for an object's current state:
    throw System.InvalidOperationException

When an operation is performed on an object that has been disposed:
    throw System.ObjectDisposedException

When an operation is not supported (such as in an overridden Stream.Write in a Stream opened for reading):
    throw System.NotSupportedException (DO NOT throw System.NotImplementedException)

When a conversion would result in an overflow (such as in a explicit cast operator overload):
    throw System.OverflowException

For all other situations, consider creating your own type that derives from Exception and throwing that.

Note: Exceptions that derive from ArgumentException (including ArgumentNullException, ArgumentException, ArgumentOutOfRangeException and InvalidEnumArgumentException), InvalidOperationException (including ObjectDisposedException) and NotSupportedException should only be thrown in situations that are avoidable (such as passing a null argument) and if thrown, would indicate a bug in the calling code. The Path class is not a good example of this, it incorrect throws ArgumentException to indicate that a path is incorrectly formed, however, it does not expose any methods that can help prevent this from occurring.