So just out of curiosity I wanted to see what was special about the exception class that allowed it to be used with the keyword Throw
while a standard class is not.
It is an arbitrary choice of the designers of the CLS. Presumably they made this choice for reasons of consistency. C# follows the CLS; the requirement is enforced by the compiler for this reason, not for any technical reason related to the implementation of the Exception type.
The CLI can actually throw any object. See http://jilc.sourceforge.net/ecma_p3_cil.shtml#_Toc524462405.
i solved adding "System" as reference
try
{
}
catch (System.Exception) {}
Design Guidelines for Exceptions
Exceptions are the standard mechanism for reporting errors. Applications and libraries should not use return codes to communicate errors. The use of exceptions adds to a consistent framework design and allows error reporting from members, such as constructors, that cannot have a return type
throw (C# Reference)
The thrown exception is an object whose class is derived from System.Exception, as shown in the following example.
class MyException : System.Exception {}
// ...
throw new MyException();
Exceptions Overview
In the .NET Framework, an exception is an object that inherits from the Exception Class
So, your exception must derive from System.Exception
, but it's up to you, how you organize it within.
I think your premise is mistaken. It is possible that an object is thrown that is not derived from System.Exception
. You just can't throw it in C# or examine the object in a catch clause. From section 8.10 of the C# spec (v4.0):
Some programming languages may support exceptions that are not representable as an object derived from System.Exception, although such exceptions could never be generated by C# code. A general catch clause may be used to catch such exceptions. Thus, a general catch clause is semantically different from one that specifies the type System.Exception, in that the former may also catch exceptions from other languages.
An example of a general catch:
try
{
}
catch (Exception) { } // 'specific' catch
catch { } // 'general' catch
In particular, this is important when calling unmanaged code.
Some types always seem to get special treatment in every language. Mostly because they are so fundamental to the system. System.Exception
, System.ValueType
, System.Delegate
are all special types in C# that are tightly bound to language keywords and the CLR, so it is not surprising that you can't just implement classes that take over their roles.
The language uses System.Exception
as a base for all exceptions. This essentially means that any throwable or catchable exception shouldn't error out if you do (Exception)myExc
. This is probably because the definition of the System.Exception
class is used so that all exceptions adhere to the same interface. Because of the consistent interface, exceptions arrive with a stack trace and a meaningful message (for example), which is invaluable for logging.
One reason why every exception needs to have a universal base class is so you can catch every type of exception in a single catch block.
If I have this:
try
{
...
}
catch(Exception ex)
{
// Handle somehow
}
That will catch ALL exceptions, and will allow me to display what it is (by using ex.Message
).
If you could throw anything, then how would you have a catch that would catch everything and still give you access to the object thrown?
You could have this, which will catch absolutely everything:
try
{
...
}
catch
{
// Handle somehow
}
But you have 'lost' the thing that was thrown.