【C#入門】usingステートメントで自動開放(Dispose、Closeの代替)

usingステートメントって使ってますか? usingステートメントを使うことで、例えばファイルの読み込みなどのリソースを開放する場合に使うDisposeメソッドなどの記述を省略することができます。

try-catch-finally文のfinallyブロックでDisposeメソッドを呼び出すのと同じ結果になるので、finallyブロックを記述する必要もないので便利です。

この記事では、usingステートメントについて

  • usingステートメントとは
  • try-catch文でDispose、Closeを使う場合
  • usingステートメントの使い方
  • 複数行のusingステートメントの使い方

など基本的な内容から、応用的な使い方の内容についても解説していきます。今回はusingステートメントについて、使い方をわかりやすく解説します!

usingステートメントとは

usingステートメントとは、使い終わったらリソースを開放する必要がある場合に、自動的にDisposeメソッドを呼び出してくれる記述形式です。

Disposeメソッドとは、IDisposableインターフェースで宣言されているメソッドです。例えば、ファイルの入出力を扱うクラスのように使い終わったらリソースを開放する必要があるクラスは、このIDisposableインターフェースを実装してDisposeメソッドを使ってリソースを開放するようにしています。

このusingステートメントを使うと、try-catch-finally文のfinallyブロックを記述する必要がありません。Close処理やDispose処理を忘れてメモリリークが発生するのを防げるのでとても便利です。

名前空間の呼び出しとの違い

usingというと、名前空間の呼び出す場合にも記述しますので少し混乱するかもしれません。

コードを記述する時の

using System;

などです。今回お伝えしているusingステートメントはこの名前空間を呼び出すモノとは違います

try-catch文でDispose、Closeを使う場合

それではまずはtry-catch-finally文でDisposeメソッドを使ってリソースを開放する方法についてみていきましょう。

using System;
using System.IO;

namespace Sample
{
  class Sample
  {
    static void Main()
    {
      FileStream fs = null;
      try {
        fs = new FileStream("test.txt", FileMode.Open);
      } catch(FileNotFoundException e) {
        Console.WriteLine("ファイルが見つかりませんでした");
      }
      finally {
        if(fs != null) {
            fs.Dispose();
        }
      }
      
      Console.ReadKey();
    }
  }
}

実行結果:

ファイルが見つかりませんでした

このサンプルでは、FileStreamクラスのオブジェクトfsを生成しています。

FileStreamクラスはコンストラクタで指定したファイルが見つからなかった場合に、例外が発生しますので、catchブロックでその場合の例外処理を記述しています。

また、オブジェクトがnull以外の場合は処理が終わったらDisposeメソッドを使ってリソースを開放しています。この場合は、ファイルを開いた後の閉じる処理なので、Disposeメソッドの代わりにCloseメソッドでも構いません

usingステートメントの使い方

それでは、先ほどのサンプルコードをusingステートメントで記述してみましょう。

using System;
using System.IO;

namespace Sample
{
  class Sample
  {
    static void Main()
    {
      try {
        using (FileStream fs = new FileStream("test.txt", FileMode.Open)) {
          
        }
          
      } catch (FileNotFoundException e) {
        Console.WriteLine("ファイルが見つかりませんでした");
      }
      
      Console.ReadKey();
    }
  }
}

実行結果:

ファイルが見つかりませんでした

このサンプルコードでは、usingステートメントを使ってtry-catch-finally文のfinallブロックのDisposeメソッドの記述を省略しています。指定したファイルが見つからない例外に対してはtry-catch文で例外処理を行っています。

ちなみに、usingステートの「( )」(カッコ)内では最後に「;」(セミコロン)を記述しません。

複数行のusingステートメントの使い方

usingステートメントは複数行並べて記述することもネスト(入れ子)で記述することもできます。

サンプルコードで確認しましょう。

using System;
using System.IO;

namespace Sample
{
  class Sample
  {
    static void Main()
    {
      try {
        using (FileStream fs = new FileStream("test.txt", FileMode.Open)) {
          using(StreamReader sr = new StreamReader(fs)) {
            Console.WriteLine(sr.ReadToEnd());
          }
        }
          
      } catch (FileNotFoundException e) {
        Console.WriteLine("ファイルが見つかりませんでした");
      }
      
      Console.ReadKey();
    }
  }
}

このサンプルコードでは、FileStreamクラスのオブジェクトfsを生成しています。またそのオブジェクトfsを使って、StreamReaderクラスのオブジェクトsrを生成しています。

この場合、usingステートメントをネスト(入れ子)で使うことで、オブジェクトfsおよびsrをDisposeメソッドを使って開放する必要はありません。例えば、ネストの内側のusing(StreamReader sr = new StreamReader(fs))ブロック内でエラー処理が発生したとしても、オブジェクトsrはもちろんですが外側のオブジェクトfsもリソースが開放されます。

また、以下ののようにusingステートメントを2つ並べて記述しても、同じ処理が行われます。

using System;
using System.IO;

namespace Sample
{
  class Sample
  {
    static void Main()
    {
      try {
        using (FileStream fs = new FileStream("test.txt", FileMode.Open))
        using(StreamReader sr = new StreamReader(fs)) {
          Console.WriteLine(sr.ReadToEnd());
        }
      } catch (FileNotFoundException e) {
        Console.WriteLine("ファイルが見つかりませんでした");
      }
      
      Console.ReadKey();
    }
  }
}

まとめ

ここでは、usingステートメントについて説明しました。

usingステートメントはDisposeメソッドやCloseメソッドを使ってリソースを開放する必要がある場合に使うと、開放処理をし忘れることがなくなるので便利です。

C言語やJavaでは使われない記述形式ですので、慣れるまでは難しく感じるかもしれませんが、バグの発生を防止することができますので、使いこなすことができるように、この記事を何度も参考にして下さいね!

LINEで送る
Pocket

「プログラミング、右も左もわからない…」という方にオススメ

当プログラミングスクール「侍エンジニア塾」では、これまで6000人以上のエンジニアを輩出してきました。

その経験を通してプログラミング学習に成功する人は、「目的目標が明確でそれに合わせた学習プランがあること」「常に相談できる人がそばにいること」「自己解決能力が身につくこと」この3つが根付いている傾向を発見しました。

侍エンジニア塾は上記3つの成功ポイントを満たすようなサービス設計に磨きをかけております。

cta_under_bnr

「自分のスタイルや目的に合わせて学習を進めたいな」とお考えの方は、ぜひチェックしてみてください。

書いた人

長野 透

長野 透

熊本在住のフリープログラマ兼ライターです。C/C++/C#、Java、Python、HTML/CSS、PHPを使ってプログラミングをしています。専門は画像処理で最近は機械学習、ディープラーニングにはまっています。幅広くやってきた経験を活かしてポイントをわかりやすくお伝えしようと思います。
お問合せはこちらでも受け付けています。
[email protected]

おすすめコンテンツ

いまならレッスン期間が2週間延長!この秋、プログラミングを学ぼう

転職成功で受講料0円!あなたもプログラミングを学んでエンジニアデビュー