General Catch Block






General Catch Block

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.

Catching Different Exception Types

public sealed class Program
{
  public static void Main()
  {
      try
      {
              // ...
              throw new ApplicationException(
                  "Arbitrary exception");
              // ...
      }
      catch (NullReferenceException exception)
      {
          // Handle NullReferenceException
      }
      catch (ArgumentException exception)
      {
          // Handle ArgumentException
      }
      catch (ApplicationException exception)
      {
          // Handle ApplicationException
       }
      catch (SystemException exception)
      {
          // Handle SystemException
      }
      catch (Exception exception)
      {
          // Handle Exception 
      }
      catch                                                     
      {                                                         
          // Any unhandled exception                             
      }                                                         

    }
  }

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.

Advanced Topic: Empty Catch Block Internals

The CIL code corresponding to an empty catch block is, in fact, a catch(object ) block. This means that regardless of the type thrown, the empty catch block will catch it. Interestingly, it is not possible to explicitly declare a catch(object ) exception block within C# code. Therefore, there is no means of catching a non-System.Exception-derived exception and having the exception instance to scrutinize.

Ironically, unmanaged exceptions from languages like C++ generally result in System.Runtime.InteropServices.SEHException type exceptions, which derive from the System.Exception type. Therefore, not only can the unmanaged type exceptions be caught using a general catch block, but also the non-System.Exception-managed types that are thrown as wellfor instance, types such as string.




 Python   SQL   Java   php   Perl 
 game development   web development   internet   *nix   graphics   hardware 
 telecommunications   C++ 
 Flash   Active Directory   Windows