20

If throwing System.Exception is considered so bad, why wasn't Exception made abstract in the first place?

That way, it would not be possible to call:

throw new Exception("Error occurred.");

This would enforce using derived exceptions to provide more details about the error that occurred.

For example, when I want to provide a custom exception hierarchy for a library, I usually declare an abstract base class for my exceptions:

public abstract class CustomExceptionBase : Exception
{
    /* some stuff here */
}

And then some derived exception with a more specific purpose:

public class DerivedCustomException : CustomExceptionBase
{
    /* some more specific stuff here */
}

Then when calling any library method, one could have this generic try/catch block to directly catch any error coming from the library:

try
{
    /* library calls here */
}
catch (CustomExceptionBase ex)
{
    /* exception handling */
}

Is this a good practice?

Would it be good if Exception was made abstract?

EDIT : My point here is that even if an exception class is marked abstract, you can still catch it in a catch-all block. Making it abstract is only a way to forbid programmers to throw a "super-wide" exception. Usually, when you voluntarily throw an exception, you should know what type it is and why it happened. Thus enforcing to throw a more specific exception type.

marco-fiset
  • 8,791

2 Answers2

13

I don't know the actual reasons why it was done this way, and to a certrain degree I agree that preventing infintely wide exceptions from being thrown would be a good thing.

BUT... when coding small demo apps or proof-of-concepts, I don't want to start designing 10 different exception sub-classes, or spending time trying to decide which is the "best" exception class for the situation. I'd rather just throw Exception and pass a string that explains the details. When it's throw-away code, I don't care about these things and if I was forced to care about such things, I'd either create my own GenericException class and throw that everywhere, or move to a different tool/language. For some projects, I agree that properly creating relevant Exception subclasses is important, but not all projects require that.

3

Possibility A: It's logically correct.

You are correct that Microsoft, along with many others do not suggest throwing a new Exception() directly for a plethora of reasons.

That being said, we can consider the academic ideal that the purpose of a the Exception class hierarchy is to define a narrowing effect so that only the most specific exceptions can be caught. (i.e. ArgumentNullException is narrower than ArgumentException).

The Exception class is no exception (pun not intended). It is intended to be the broadest possible exception, a "super exception" that almost cannot be caught because its scope is infinitely wide. 'Exception' it is not abstract in the sense that Exception cannot exist as an entity on its own. It can (though admittedly no good cases are defined yet - see Possibility B), and therefore should be publicly constructible.

The 'abstract' keyword (in a purely academic sense) is only applicable when the base class makes no sense on its own - i.e. FourLeggedAnimal.

All of this in mind, there would be no technical reason to make the class abstract, other than to be a source of aggravation to developers.

Possibility B: Design Lock-in / They didn't know

If MS made this class abstract, they may have been in trouble if they changed their mind down the road, as this class is very essential to the fundamentals of the language. They already goofed with ApplicationException, so it's foreseeable that they anticipated a change in recommendation down the road, too. (see Link)

There may be other reasons (I am thinking maybe this has to do with Reflection, or some other technical reason), so I am making this post a CW.

Glorfindel
  • 3,167