try-finally (C# リファレンス)try-finally (C# Reference)

finally ブロックを使用すると、try ブロックで割り当てられたリソースをクリーンアップし、try ブロックで例外が発生してもコードを実行することができます。By using a finally block, you can clean up any resources that are allocated in a try block, and you can run code even if an exception occurs in the try block. 通常、制御が finally ステートメントを離れると、try ブロックのステートメントが実行されます。Typically, the statements of a finally block run when control leaves a try statement. 制御の移動は、break ステートメント、continue ステートメント、goto ステートメント、return またはステートメントの正常な実行の結果や、try ステートメントで生じた例外の反映の結果として生じます。The transfer of control can occur as a result of normal execution, of execution of a break, continue, goto, or return statement, or of propagation of an exception out of the try statement.

ハンドルされている例外では、関連する finally ブロックの実行が保証されます。Within a handled exception, the associated finally block is guaranteed to be run. ただし、例外がハンドルされていない場合、finally ブロックの実行は、例外のアンワインド操作のトリガー方法に依存します。However, if the exception is unhandled, execution of the finally block is dependent on how the exception unwind operation is triggered. つまり、コンピューターの設定に依存するということでもあります。That, in turn, is dependent on how your computer is set up.

通常、ハンドルされていない例外によってアプリケーションが終了した場合、finally ブロックが実行されるかどうかは重要ではありません。Usually, when an unhandled exception ends an application, whether or not the finally block is run is not important. ただし、このような状況でも実行する必要のあるステートメントが finally ブロックにある場合は、try-finally ステートメントに catch ブロックを追加するという方法があります。However, if you have statements in a finally block that must be run even in that situation, one solution is to add a catch block to the try-finally statement. または、try-finally ステートメントの try ブロックでスローされた例外があれば、コール スタックの上の方でキャッチすることもできます。Alternatively, you can catch the exception that might be thrown in the try block of a try-finally statement higher up the call stack. つまり、try-finally ステートメントが含まれているメソッドを呼び出すメソッド内でも、そのメソッドを呼び出すメソッド内でも、コール スタック内の任意のメソッド内でも、例外をキャッチできるということです。That is, you can catch the exception in the method that calls the method that contains the try-finally statement, or in the method that calls that method, or in any method in the call stack. 例外がキャッチされない場合、finally ブロックの実行は、例外のアンワインド操作がオペレーティング システムによってトリガーされるかどうかに依存します。If the exception is not caught, execution of the finally block depends on whether the operating system chooses to trigger an exception unwind operation.

Example

次の例では、無効な変換ステートメントによって System.InvalidCastException 例外が発生しています。In the following example, an invalid conversion statement causes a System.InvalidCastException exception. この例外はハンドルされていません。The exception is unhandled.

public class ThrowTestA
{
    static void Main()
    {
        int i = 123;
        string s = "Some string";
        object obj = s;

        try
        {
            // Invalid conversion; obj contains a string, not a numeric type.
            i = (int)obj;

            // The following statement is not run.
            Console.WriteLine("WriteLine at the end of the try block.");
        }
        finally
        {
            // To run the program in Visual Studio, type CTRL+F5. Then 
            // click Cancel in the error dialog.
            Console.WriteLine("\nExecution of the finally block after an unhandled\n" +
                "error depends on how the exception unwind operation is triggered.");
            Console.WriteLine("i = {0}", i);
        }
    }
    // Output:
    // Unhandled Exception: System.InvalidCastException: Specified cast is not valid.
    //
    // Execution of the finally block after an unhandled
    // error depends on how the exception unwind operation is triggered.
    // i = 123
}

次の例では、コール スタックのずっと上の方のメソッド内で TryCast メソッドからの例外がキャッチされます。In the following example, an exception from the TryCast method is caught in a method farther up the call stack.

public class ThrowTestB
{
    static void Main()
    {
        try
        {
            // TryCast produces an unhandled exception.
            TryCast();
        }
        catch (Exception ex)
        {
            // Catch the exception that is unhandled in TryCast.
            Console.WriteLine
                ("Catching the {0} exception triggers the finally block.",
                ex.GetType());

            // Restore the original unhandled exception. You might not
            // know what exception to expect, or how to handle it, so pass 
            // it on.
            throw;
        }
    }

    public static void TryCast()
    {
        int i = 123;
        string s = "Some string";
        object obj = s;

        try
        {
            // Invalid conversion; obj contains a string, not a numeric type.
            i = (int)obj;

            // The following statement is not run.
            Console.WriteLine("WriteLine at the end of the try block.");
        }
        finally
        {
            // Report that the finally block is run, and show that the value of
            // i has not been changed.
            Console.WriteLine("\nIn the finally block in TryCast, i = {0}.\n", i);
        }
    }
    // Output:
    // In the finally block in TryCast, i = 123.

    // Catching the System.InvalidCastException exception triggers the finally block.

    // Unhandled Exception: System.InvalidCastException: Specified cast is not valid.
}

finally の詳細については、「try-catch-finally」を参照してください。For more information about finally, see try-catch-finally.

C# には、IDisposable オブジェクトに対して同様の機能を便利な構文で提供する using ステートメントも含まれています。C# also contains the using statement, which provides similar functionality for IDisposable objects in a convenient syntax.

C# 言語仕様C# language specification

詳細については、「C# 言語仕様」の「try ステートメント」セクションを参照してください。For more information, see The try statement section of the C# language specification.

関連項目See also