It is a little known fact (and probably for the best) that the CLR can throw and catch more than just System.Exception and its children. In fact, the CLR can use any type as if it was an Exception.
.assembly ExceptionTestAssembly {}
.class public ExceptionTest { //custom class
//note that ExceptionTest does NOT extend System.Exception
.method public void .ctor(){
.maxstack 1
ret
}
.method static void main() il managed{
.entrypoint //program entry point...
.try {
newobj instance void ExceptionTest::.ctor()
throw //throw a random object
} catch ExceptionTest { //catch the random object
pop
ldstr "Random object caught"
call void [mscorlib]System.Console::WriteLine(string)
leave.s OUT
}
OUT: ret
}
}
In the above code example I have defined my own class (which does not extend System.Exception), and both throw and catch it. This code sample was written in IL because every other .NET language does not allow throwing random objects.
What is the point of this, you ask? Nothing more than to provide insight into the CLR. I would not, and am glad that C# does not allow you too, actual do this. While possible, it violates the CTS contract that good .NET languages abide by.