using ステートメント (C# リファレンス)

using ステートメントは、IDisposable オブジェクトの正しい使用を保証する簡易構文を提供します。 await using ステートメントによって IAsyncDisposable オブジェクトが適切に使用されるようになります。 この言語では、System.IAsyncDisposable インターフェイスを実装する非同期の破棄可能な型がサポートされます。

using ステートメントを使用する方法の例を次に示します。

string manyLines = @"This is line one
This is line two
Here is line three
The penultimate line is line four
This is the final, fifth line.";

using (var reader = new StringReader(manyLines))
{
    string? item;
    do
    {
        item = reader.ReadLine();
        Console.WriteLine(item);
    } while (item != null);
}

"using 宣言" に中括弧は不要です。

string manyLines = @"This is line one
This is line two
Here is line three
The penultimate line is line four
This is the final, fifth line.";

using var reader = new StringReader(manyLines);
string? item;
do
{
    item = reader.ReadLine();
    Console.WriteLine(item);
} while (item != null);

Remarks

FileFont は、アンマネージド リソース (この場合はファイル ハンドルとデバイス コンテキスト) にアクセスするマネージド型の例です。 アンマネージ リソースや、それをカプセル化するクラス ライブラリ型は他にもたくさんあります。 このようなすべての型は、IDisposable インターフェイスまたは IAsyncDisposable インターフェイスを実装する必要があります。

IDisposable オブジェクトの有効期間が 1 つのメソッドに限定されているとき、それを using ステートメントまたは using 宣言で宣言し、インスタンス化してください。 using 宣言では、範囲から外れたとき、正しい方法で、オブジェクト上で Dispose メソッドが呼び出されます。 using ステートメントでは、Dispose が呼び出された直後、オブジェクト自体が範囲から外れます。 オブジェクトは、using ブロック内では読み取り専用です。変更したり再割り当てしたりすることはできません。 using 宣言で宣言された変数は読み取り専用です。 オブジェクトに IDisposable ではなく IAsyncDisposable が実装されている場合、いずれかの using フォームから DisposeAsync が呼び出され、返される ValueTaskawaits を行います。 IAsyncDisposable の詳細については、「IAsyncDisposable」を参照してください。

両方の using フォームにより、using ブロック内で例外が発生した場合でも必ず Dispose (または DisposeAsync) が呼び出されます。 オブジェクトを try ブロックに配置し、finally ブロック内で Dispose (または DisposeAsync) を呼び出しても、同じ結果が得られます。実際には、コンパイラによって using ステートメントと using 宣言がこのように変換されます。 前のコード例は、コンパイル時に次のコードに展開されます (オブジェクトのスコープ制限を定義する中かっこが加えられていることに注意してください)。

string manyLines = @"This is line one
This is line two
Here is line three
The penultimate line is line four
This is the final, fifth line.";

{
    var reader = new StringReader(manyLines);
    try
    {
        string? item;
        do
        {
            item = reader.ReadLine();
            Console.WriteLine(item);
        } while (item != null);
    }
    finally
    {
        reader?.Dispose();
    }
}

新しい using ステートメントの構文は似たコードに変換されます。 変数が宣言されている場所で try ブロックが開きます。 finally ブロックは、囲んでいるブロックの終わり、通常はメソッドの最後に追加されます。

try-finally ステートメントの詳細については、「try」の記事を参照してください。

次の例のように、1 つの using ステートメントで型の複数のインスタンスを宣言できます。 1 つのステートメントで複数の変数を宣言する場合、暗黙的に型指定された変数 (var) を使用できないことに注意してください。

string numbers = @"One
Two
Three
Four.";
string letters = @"A
B
C
D.";

using (StringReader left = new StringReader(numbers),
    right = new StringReader(letters))
{
    string? item;
    do
    {
        item = left.ReadLine();
        Console.Write(item);
        Console.Write("    ");
        item = right.ReadLine();
        Console.WriteLine(item);
    } while (item != null);
}

次の例に示すように、宣言構文を使用し、同じ型の複数の宣言を組み合わせることができます。

string numbers = @"One
Two
Three
Four.";
string letters = @"A
B
C
D.";

using StringReader left = new StringReader(numbers),
    right = new StringReader(letters);
string? item;
do
{
    item = left.ReadLine();
    Console.Write(item);
    Console.Write("    ");
    item = right.ReadLine();
    Console.WriteLine(item);
} while (item != null);

リソース オブジェクトをインスタンス化してから、変数を using ステートメントに渡すことはできますが、これはベスト プラクティスではありません。 この場合、アンマネージド リソースへのアクセスがなくなっている可能性が高いのにもかかわらず、制御が using ブロックを離れた後もオブジェクトはスコープ内に残ります。 つまり、完全に初期化されることはなくなります。 using ブロックの外側でオブジェクトを使用しようとすると、例外がスローされる可能性があります。 このため、オブジェクトを using ステートメントでインスタンス化して、そのスコープを using ブロックに制限することをお勧めします。

string manyLines = @"This is line one
This is line two
Here is line three
The penultimate line is line four
This is the final, fifth line.";

var reader = new StringReader(manyLines);
using (reader)
{
    string? item;
    do
    {
        item = reader.ReadLine();
        Console.WriteLine(item);
    } while (item != null);
}
// reader is in scope here, but has been disposed

IDisposable オブジェクトの破棄に関する詳細については、「IDisposable」を参照してください。

C# 言語仕様

詳細については、C# 言語仕様に関するページの using ステートメントに関するセクションを参照してください。 言語仕様は、C# の構文と使用法に関する信頼性のある情報源です。

関連項目