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,721
  • 9
  • 35
  • 46
  • 4
    +1 _"The best way to prevent incorrect use is to make such use impossible."_ - [Scott Meyers](http://programmer.97things.oreilly.com/wiki/index.php/Make_Interfaces_Easy_to_Use_Correctly_and_Hard_to_Use_Incorrectly) – Steven Jeuris Nov 14 '11 at 16:04
  • 5
    *"Would it be good if Exception was made abstract?"* - Abslutely not, because all of the existing .NET code which uses new Exception("...") would break. However, *"Should the .NET team have made Exception abstract to begin with?"* - probably, yes, but it's >10 years too late now :) – MattDavey Nov 14 '11 at 17:00

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.

FrustratedWithFormsDesigner
  • 46,105
  • 7
  • 126
  • 176
  • I completely agree with you, but the question was implicitly thinking about non-trivial projects. – marco-fiset Nov 14 '11 at 19:34
  • It's also the kind of issue that humans easily work around. Once `Exception` is no longer available as a quick option (such as in demo's), then people will start using some other exception type as their goto "some exception" type. – Flater Jul 20 '22 at 08:57
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,137
  • 6
  • 25
  • 33
Kevin McCormick
  • 4,064
  • 1
  • 18
  • 28
  • _"Just because it is "super-wide", it is not abstract."_ ... But that's the OP's argument isn't it. Shouldn't it be abstract in the sense that some indication of the type of exception always needs to be passed. – Steven Jeuris Nov 14 '11 at 15:59
  • Good point, I will update my answer accordingly - the nature of this question is a little confusing because 'abstract' is both a language keyword as well as the name of the concept being discussed. – Kevin McCormick Nov 14 '11 at 16:45
  • @KevinMcCormick : The term 'abstract' here is used as the language keyword. Please tell me how I can change my question so it is clearer for future readers ? – marco-fiset Nov 14 '11 at 16:59
  • I think it's a great question. Any OO conversion regarding the `abstract` keyword hits this wall. Not sure of any way to get around it other than denoting the `abstract` keyword with the backticks. – Kevin McCormick Nov 14 '11 at 17:01
  • 2
    How is "disabstracting" a class a breaking change? – configurator Nov 14 '11 at 17:03
  • @configurator, Good point, I am actually not sure if it would be technically a breaking change, though this would certainly be a pain if say, they 'disabstracted' it in 2.0 but not in 1.1 (even worse in the other direction). Regardless, my thought is that it would be a breaking change in a recommendation sense. If it were abstract, MS wouldn't be able to later on say, "nevermind, go ahead and create instances of Exception - oh wait, you can't because we made that assumption during the design of the FX". The Design Guidelines, fxCop, etc. all came out after .NET 1 was released. – Kevin McCormick Nov 14 '11 at 17:09
  • [Previously I searched high and low](http://programmers.stackexchange.com/questions/46004/pure-virtual-or-abstract-whats-in-a-name/47932#47932) for the _"The 'abstract' keyword (in a purely academic sense)"_, and I found no such definitions. – Steven Jeuris Nov 14 '11 at 19:15
  • Fair enough, I can't find any formal definition either. I guess it was based purely on my idea that an `abstract` class defines an incomplete object, where inheritance is necessary in order for it to be functional. `Exception` does not require any added functionality in order to be functional - it is only a recommendation (albeit a strong one) that a subclass be used. – Kevin McCormick Nov 14 '11 at 19:42