Поделиться через


Exception Handling (C# Programming Guide)

A try block is used by C# programmers to partition code that might be affected by an exception. Associated catch blocks are used to handle any resulting exceptions. A finally block contains code that is run regardless of whether or not an exception is thrown in the try block, such as releasing resources that are allocated in the try block. A try block requires one or more associated catch blocks, or a finally block, or both.

The following examples show a try-catch statement, a try-finally statement, and a try-catch-finally statement.

try
{
    // Code to try goes here.
}
catch (SomeSpecificException ex)
{
    // Code to handle the exception goes here.
    // Only catch exceptions that you know how to handle.
    // Never catch base class System.Exception without
    // rethrowing it at the end of the catch block.
}
try
{
    // Code to try goes here.
}
finally
{
    // Code to execute after the try block goes here.
}
try
{
    // Code to try goes here.
}
catch (SomeSpecificException ex)
{
    // Code to handle the exception goes here.
}
finally
{
    // Code to execute after the try (and possibly catch) blocks 
    // goes here.
}

A try block without a catch or finally block causes a compiler error.

Catch Blocks

A catch block can specify the type of exception to catch. The type specification is called an exception filter. The exception type should be derived from Exception. In general, do not specify Exception as the exception filter unless either you know how to handle all exceptions that might be thrown in the try block, or you have included a throw statement at the end of your catch block.

Multiple catch blocks with different exception filters can be chained together. The catch blocks are evaluated from top to bottom in your code, but only one catch block is executed for each exception that is thrown. The first catch block that specifies the exact type or a base class of the thrown exception is executed. If no catch block specifies a matching exception filter, a catch block that does not have a filter is selected, if one is present in the statement. It is important to position catch blocks with the most specific (that is, the most derived) exception types first.

You should catch exceptions when the following conditions are true:

  • You have a good understanding of why the exception might be thrown, and you can implement a specific recovery, such as prompting the user to enter a new file name when you catch a FileNotFoundException object.

  • You can create and throw a new, more specific exception.

    int GetInt(int[] array, int index)
    {
        try
        {
            return array[index];
        }
        catch(System.IndexOutOfRangeException e)
        {
            throw new System.ArgumentOutOfRangeException(
                "Parameter index is out of range.");
        }
    }
    
  • You want to partially handle an exception before passing it on for additional handling. In the following example, a catch block is used to add an entry to an error log before re-throwing the exception.

    try
    {
        // Try to access a resource.
    }
    catch (System.UnauthorizedAccessException e)
    {
        // Call a custom error logging procedure.
        LogError(e);
        // Re-throw the error.
        throw;     
    }
    

Finally Blocks

A finally block enables you to clean up actions that are performed in a try block. If present, the finally block executes last, after the try block and any matched catch block. A finally block always runs, regardless of whether an exception is thrown or a catch block matching the exception type is found.

The finally block can be used to release resources such as file streams, database connections, and graphics handles without waiting for the garbage collector in the runtime to finalize the objects. See using Statement (C# Reference) for more information.

In the following example, the finally block is used to close a file that is opened in the try block. Notice that the state of the file handle is checked before the file is closed. If the try block cannot open the file, the file handle still has the value null and the finally block does not try to close it. Alternatively, if the file is opened successfully in the try block, the finally block closes the open file.

System.IO.FileStream file = null;
System.IO.FileInfo fileinfo = new System.IO.FileInfo("C:\\file.txt");
try
{
    file = fileinfo.OpenWrite();
    file.WriteByte(0xF);
}
finally
{
    // Check for null because OpenWrite might have failed.
    if (file != null)
    {
        file.Close();
    }
}

C# Language Specification

For more information, see the C# Language Specification. The language specification is the definitive source for C# syntax and usage.

See Also

Reference

Exceptions and Exception Handling (C# Programming Guide)

try-catch (C# Reference)

try-finally (C# Reference)

try-catch-finally (C# Reference)

using Statement (C# Reference)

Concepts

C# Programming Guide

Other Resources

C# Reference