最初に
どうも、ろっさむです。
今回は様々なusing
の使い方を紹介する記事となります。
環境は以下の通りです。
- Windows10
- JetBrains Rider
usingの使い方
ざっと以下の4つの使い方があります。
- usingディレクティブ
- usingエイリアスディレクティブ
- using静的ディレクティブ
- usingステートメント
一つずつ見ていきましょう。
usingディレクティブ
これは馴染みのある人が多いと思います。
異なる名前空間に定義されているクラスを使用する場合には System.Collections.Generic.List<int> numbers;
のように「名前空間.クラス名」と記述する必要があります。ここでusingディレクティブをファイルの頭で使用することで、以下のように名前空間の指定を省略して記述できるようになります。
using System.Collections.Generic;
class TestProgram
{
static void Main(string[] args)
{
List<int> index;
}
}
usingエイリアスディレクティブ
こちらはtypedef
のように使えるusing エイリアス(別名) ディレクティブという機能です。
名前の通り、名前空間に別名を付けることができます。
using Ints = System.Collections.Generic.List<int>;
class TestProgram
{
static void Main(string[] args)
{
var index = new Ints();
}
}
using静的ディレクティブ
C#6.0から使える機能です。
usingディレクティブの機能と同じことが静的メソッドにも適用できるようになります。また、列挙型のメンバーも静的なため、この機能が適用できます。
using System;
using static System.Enum;
using static Colors;
enum Colors
{
Red,
Yellow,
Blue,
White,
Black,
}
class TestProgram
{
static void Main(string[] args)
{
// using static System.Enum がない場合は Enum.GetValues と書く必要がある。
foreach (int color in GetValues(typeof(Colors)))
{
Console.WriteLine(color);
}
// using static Colors がない場合は Colors.Blue と書く必要がある。
var myFavoriteColor = Blue;
}
}
usingステートメント
普段インスタンス化されたオブジェクトはGCによって管理され、自動で破棄が行われます。ですがファイルなどのアンマネージド リソースを使用する場合はGCの管理対象外となり、以下の流れが必要となります。
- リソースを使用する権利を取得
- リソースに対する操作を行う
- リソースの使用権を破棄する
この、「リソースの使用権を破棄する」を怠ると、ファイルにロックがかかった状態のまま開きっぱなしになって他の処理からアクセスできなくなったり面倒なことが起こります。
なのでtry-catch-finallyを使用した上で、処理を行います。finallyは例外が発生しても必ず実行されるブロックなので、ここでリソースの使用権を破棄するためのClose()
を呼び出します。
class TestProgram
{
static void Main(string[] args)
{
// リソースを使用する権利取得:コンストラクタ(ファイルパス, ファイル操作のモード,
// ファイル操作でのアクセスレベル, ファイルを開いている間の他のプログラムからのアクセス許可レベル = Noneは不許可)
FileStream fs = new FileStream("hoge.txt", FileMode.Open, FileAccess.Read, FileShare.None);
try
{
// 何かしらの処理
}
catch (Exception e)
{
// 例外処理
}
finally
{
if(fs != null)
fs.Close();
}
}
}
しかし、アンマネージド リソースを使用する場合に、毎回これを書くのは面倒くさいかと思います。
ここでusingステートメントという機能を用いることで簡潔に書くことができるようになります。
usingステートメントを用いることで、コンパイラ側で自動的にリソースの破棄用のILを生成します。
class TestProgram
{
static void Main(string[] args)
{
using (FileStream fs = new FileStream("hoge.txt", FileMode.Open, FileAccess.Read, FileShare.None))
{
Console.WriteLine(fs.Length);
}
}
}
ただしこの記述は IDisposable
を実装するクラスのみに使用できます。
更にC#8.0からは以下のように、変数宣言時にusing
をつけることで更なる簡略化ができるようになりました。
class TestProgram
{
static void Main(string[] args)
{
using var fs = new FileStream("hoge.txt", FileMode.Open, FileAccess.Read, FileShare.None);
Console.WriteLine(fs.Length);
}
}