The .NET exception hirarchy is somewhat stupid. I would take Exception like
OutOfMemory,
StackOverflow, InvalidProgram,NullReference and similar in another branch of
the hirarchy since nobody ever might want to throw them and they are really
rare circumstances when you want to catch them.
I agree. It needs to be organized in a more hierarchal manner. The current
methodology is that because no one can figure out what a decent hierarchy
would look like they have fallen back on the position that the hierarchy
should be flat and wide (many types, few if any derived from any other).
At a minimum I would separate fatal from non-fatal exceptions. I would put
StackOverflow, OutOfMemory, and ExecutionEngine in that category. I think
the system will shutdown anyway whenever one of those occurs. I disagree
about some of the others you mention, but some sort of categorization would
be useful.
What will a wrog call to an Indexer throw? IndexOutOfRangeException or
ArgumentOutOfRangeException?
Again both are in a completely other branch or the exception hirarchy no you
have to catch either both or catch System.Exception.
but
I know it is stupid to catch Exception but often is is really the most
secure way.
I agree. I believe that in some cases it is entirely appropriate to do so.
However, this depends to a large extend on the software component - a
library should do little catching, and rarely should it catch everything.
However, a client GUI may need to catch everything so that the application
does not crash unexpectedly just because a bug in library control forgets to
catch a particular exception.
This is even more of a problem when a control that only catches a few
specific exceptions is part of a system that undergoes evolution. Some
component that the library uses may now throw a new exception that it was
not expecting, If the client did not have a backstop catch it may crash.
I suggest Microsoft should have designed there Exception hirarchy better.
This is how I would have it done:
SystemException
- StackOverflow
- InvalidProgram,
- NullReference
- OutOfMemory
- ArithmeticException
ApplicationException
-ArgumentException
-ArgumentNull
-ArgumentOutOfRange
-IndexOutOfBounds
-FormatException
-IOException
-InvalidOperationException
So in the branch SystemException are the exception you normally may not want
to catch,
and in ApplicationException are the ones that are commonly caught in
applications. So if I have
a method that throws InvalidOperationException and later I derive my own
exception from InvalidOperationException
clients stay compatible.
Perhaps one reason why they did not do so was because it would be difficult
to get agreement on this. I think it would be a boon if they had, and even
if we disagreed on some particulars, even a minimal standard is better then
the chaos we have now.
FYI, the current word from MSFT is to deprecate the use of
ApplicationException. Instead, you should derive your custom types directly
from System.Exception.