using ステートメント - 破棄可能なオブジェクトが正しく使用されるようにする

using ステートメントによって IDisposable インスタンスが適切に使用されるようになります。

var numbers = new List<int>();
using (StreamReader reader = File.OpenText("numbers.txt"))
{
    string line;
    while ((line = reader.ReadLine()) is not null)
    {
        if (int.TryParse(line, out int number))
        {
            numbers.Add(number);
        }
    }
}

コントロールが using ステートメントのブロックを離れると、取得した IDisposable インスタンスが破棄されます。 特に、using ステートメントによって、using ステートメントのブロック内で例外が発生した場合でも、破棄可能なインスタンスが破棄されるようにします。 前の例では、開いているファイルは、すべての行が処理された後に閉じられます。

IAsyncDisposable インスタンスを正しく使用するには、await using ステートメントを使用します。

await using (var resource = new AsyncDisposableExample())
{
    // Use the resource
}

IAsyncDisposable インスタンスの使用の詳細については、「DisposeAsync メソッドの実装」記事の「非同期の破棄可能の使用」を参照してください。

中かっこを必要としない using "宣言" を使用することもできます。

static IEnumerable<int> LoadNumbers(string filePath)
{
    using StreamReader reader = File.OpenText(filePath);
    
    var numbers = new List<int>();
    string line;
    while ((line = reader.ReadLine()) is not null)
    {
        if (int.TryParse(line, out int number))
        {
            numbers.Add(number);
        }
    }
    return numbers;
}

using 宣言で宣言すると、宣言されているスコープの末尾にローカル変数が破棄されます。 前の例では、メソッドの末尾で破棄が行われます。

using ステートメントまたは宣言によって宣言された変数は読み取り専用です。 再割り当てしたり、ref または out パラメーターとして渡したりすることはできません。

次の例に示すように、1 つの using ステートメントで同じ型の複数のインスタンスを宣言できます。

using (StreamReader numbersFile = File.OpenText("numbers.txt"), wordsFile = File.OpenText("words.txt"))
{
    // Process both files
}

1 つの using ステートメントで複数のインスタンスを宣言すると、宣言の逆の順序で破棄されます。

また、using ステートメントと宣言を、使い捨てパターンに適合する ref 構造体のインスタンスと共に使用することもできます。 つまり、ここには、アクセス可能かつパラメーターなしで、void 戻り値の型が含まれる、インスタンスの Dispose メソッドが含まれています。

using ステートメントには、次の形式を指定することもできます。

using (expression)
{
    // ...
}

ここで expression は破棄可能なインスタンスを生成します。 次に例を示します。

StreamReader reader = File.OpenText(filePath);

using (reader)
{
    // Process file content
}

警告

前の例では、コントロールが using ステートメントから離れた後、破棄可能なインスタンスが既に破棄されていても、スコープ内に残ります。 そのインスタンスをさらに使用すると、例外 (例: ObjectDisposedException) が発生する可能性があります。 そのため、using ステートメント内または using 宣言で破棄可能な変数を宣言することをお勧めします。

C# 言語仕様

詳細については、C# 言語仕様using ステートメントに関するセクションと、"パターンベースの using" と "using 宣言" に関する提案ノートを参照してください。

関連項目