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

finally ブロックを使用すると、try ブロックで割り当てられたリソースをクリーンアップし、try ブロックで例外が発生してもコードを実行することができます。 通常、制御が try ステートメントを離れると、finally ブロックのステートメントが実行されます。 制御の移動は、break ステートメント、continue ステートメント、goto ステートメント、return またはステートメントの正常な実行の結果や、try ステートメントで生じた例外の反映の結果として生じます。

ハンドルされている例外では、関連する finally ブロックの実行が保証されます。 ただし、例外がハンドルされていない場合、finally ブロックの実行は、例外のアンワインド操作のトリガー方法に依存します。 つまり、コンピューターの設定に依存するということでもあります。 詳細については、「CLR のハンドルされない例外の処理」を参照してください。

通常、ハンドルされていない例外によってアプリケーションが終了した場合、finally ブロックが実行されるかどうかは重要ではありません。 ただし、このような状況でも実行する必要のあるステートメントが finally ブロックにある場合は、try-finally ステートメントに catch ブロックを追加するという方法があります。 または、try-finally ステートメントの try ブロックでスローされた例外があれば、コール スタックの上の方でキャッチすることもできます。 つまり、try-finally ステートメントが含まれているメソッドを呼び出すメソッド内でも、そのメソッドを呼び出すメソッド内でも、コール スタック内の任意のメソッド内でも、例外をキャッチできるということです。 例外がキャッチされない場合、finally ブロックの実行は、例外のアンワインド操作がオペレーティング システムによってトリガーされるかどうかに依存します。

使用例

次の例では、無効な変換ステートメントによって System.InvalidCastException 例外が発生しています。 この例外はハンドルされていません。

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 メソッドからの例外がキャッチされます。

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」を参照してください。

C# には、IDisposable オブジェクトに対して同様の機能を便利な構文で提供する using ステートメントも含まれています。

C# 言語仕様

詳細については、「C# 言語仕様」を参照してください。言語仕様は、C# の構文と使用法に関する信頼性のある情報源です。

参照

処理手順

方法 : 例外を明示的にスローする

関連項目

C# のキーワード

try、throw、および catch ステートメント (C++)

例外処理ステートメント (C# リファレンス)

throw (C# リファレンス)

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

概念

C# プログラミング ガイド

その他の技術情報

C# リファレンス