この章のテーマ §
using文について学びます。開いたファイルを必ず閉じるなどの確実な終了処理を記述するための定番です。
前提知識 §
Console.WriteLineメソッド, 文字列の基礎, 変数の基礎, クラスの基礎, メソッドの基礎, インターフェースの基礎, try-finnally構文
解説 §
using文は、確保したリソースを確実に解放するために使用する定番です。たとえばファイルは開きっぱなしにしておくと他のプロセスからアクセスできないことがあるので、使い終わったら閉じることが重要です。しかし、どんな方法でも使い終わった時点で確実に閉じるのは骨が折れます。
この問題を解決するために、try-finnally構文が利用できます。サンプルソースのsub3()がそれにあたります。finnallyを使えば、どんな方法でブロックを抜けても実行されるコードを記述できます。
しかし、同じような機能をもっとスマートに書くために、C#にはusing文が用意されています。using文は指定したブロックを抜ける際に、IDisposable.Dispose()メソッドを必ず呼び出します。
sub1()は、実行すべきコードを後続させる書式です。
sub2()は、実行すべきコードを後続させない書式です。この場合は、using文が書かれたブロックを抜ける時にIDisposable.Dispose()メソッドが呼ばれます。
罠の数々 §
- 名前空間で使うusing ディレクティブに注意。それは、このusing文と同じ名前だが違う機能を持つもの
- try-finnally構文では、IDisposable.Dispose()メソッドが自動的に呼び出されない。呼び出されて欲しいときは自分で呼び出す
- 実装するインターフェースはIAsyncDisposableでも良い
- どちらのインターフェースも実装していない場合はusing文は使えない。try-finnally構文で凌ごう
参考リンク §
using ステートメント (C# リファレンス)
サンプルソース: kw_using §
sub1();
sub2();
sub3();
void sub1()
{
using (var a = new MySapme())
{
a.Output("Pattern1");
return;
}
}
void sub2()
{
using var a = new MySapme();
a.Output("Pattern2");
return;
}
void sub3()
{
var a = new MySapme();
try
{
a.Output("Pattern3");
return;
}
finally
{
Console.WriteLine("Finally!");
}
}
class MySapme : IDisposable
{
public void Output(string message) => Console.WriteLine(message);
public void Dispose()
{
Console.WriteLine("Disposed!");
}
}
実行結果 §
Pattern1
Disposed!
Pattern2
Disposed!
Pattern3
Finally!
リポジトリ §
https://github.com/autumn009/CSharpPrimer2
練習問題 §
確実な終了処理が必要な正しい理由ではないものを選べ、
- システムの資源を不必要に浪費させない
- システムの資源を使用中にロックされる場合、ロックを最短時間で終わらせる
- どうして終了時に実行すべきコードが存在する (例:開始タグを書いたら必ず終了タグも書く)
- 特定の資源を利用中だと宣言する
- どのような資源も最終的にはいつか解放されるが、解放時期を制御したい、あるいは前倒ししたい
[[解答]]