C# requires that any object that code throws must derive from System.Exception. However, this requirement is not universal to all languages. C/C++, for example, allows any object type to be thrown, including managed exceptions that don't derive from System.Exception. In C# 1.0, the result was that method calls (into other assemblies) could potentially throw exceptions that would not be caught with a catch(System.Exception) block. If a different language throws a string, for example, the exception could go unhandled. To avoid this, C# includes a catch block that takes no parameters. The term for such a catch block is general catch block, and Listing 10.3 includes one.
Listing 10.3. Catching Different Exception Types
The general catch block will catch all exceptions, regardless of whether they derive from System.Exception, assuming an earlier catch block does not catch them. The disadvantage of such a block is simply that there is no exception instance to access and, therefore, no way to know the appropriate course of action. It wouldn't even be possible to recognize the unlikely case where such an exception is innocuous. The best course of action is to handle the exception with some cleanup code before shutting down the application. The catch block could save any volatile data, for example, before shutting down the application or rethrowing the exception.
The behavior in C# 2.0 varies slightly from the earlier C# behavior. In C# 2.0, all exceptions, whether deriving from System.Exception or not, will propagate into C# assemblies as derived from System.Exception. The result is that System.Exception catch blocks will catch all exceptions not caught by earlier blocks and a general catch block following a System.Exception catch block will never be invoked. Furthermore, general catch blocks following a System.Exception catch block will result in a compiler warning.