【C#】usingの色々な使い方

# 最初に

どうも、ろっさむです。

今回は様々な`using`の使い方を紹介する記事となります。
環境は以下の通りです。

- Windows10
- JetBrains Rider

# usingの使い方

ざっと以下の4つの使い方があります。

- usingディレクティブ
- usingエイリアスディレクティブ
- using静的ディレクティブ
- usingステートメント

一つずつ見ていきましょう。

## usingディレクティブ

これは馴染みのある人が多いと思います。

異なる名前空間に定義されているクラスを使用する場合には `System.Collections.Generic.List<int> numbers;`のように「名前空間.クラス名」と記述する必要があります。ここで**usingディレクティブ**をファイルの頭で使用することで、以下のように名前空間の指定を省略して記述できるようになります。

```c#
using System.Collections.Generic;

class TestProgram
{
	static void Main(string[] args)
	{
		List<int> index;
	}
}
```

## usingエイリアスディレクティブ

こちらは`typedef`のように使える**using エイリアス(別名) ディレクティブ**という機能です。
名前の通り、名前空間に別名を付けることができます。

```c#
using Ints = System.Collections.Generic.List<int>;

class TestProgram
{
	static void Main(string[] args)
	{
		var index = new Ints();
	}
}
```

## using静的ディレクティブ

C#6.0から使える機能です。
**usingディレクティブの機能と同じことが静的メソッドにも適用できる**ようになります。また、列挙型のメンバーも静的なため、この機能が適用できます。

```c#
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の管理対象外となり、以下の流れが必要となります。

1. リソースを使用する権利を取得
2. リソースに対する操作を行う
3. リソースの使用権を破棄する

この、「リソースの使用権を破棄する」を怠ると、ファイルにロックがかかった状態のまま開きっぱなしになって他の処理からアクセスできなくなったり面倒なことが起こります。

なのでtry-catch-finallyを使用した上で、処理を行います。finallyは例外が発生しても必ず実行されるブロックなので、ここでリソースの使用権を破棄するための`Close()`を呼び出します。

```c#
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を生成**します。

```c#
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`をつけることで更なる簡略化ができる**ようになりました。

```c#
class TestProgram
{
	static void Main(string[] args)
	{
		using var fs = new FileStream("hoge.txt", FileMode.Open, FileAccess.Read, FileShare.None);
		Console.WriteLine(fs.Length);	
	}
}
```


# 参考

- [リソースの破棄（++C++;）](https://ufcpp.net/study/csharp/oo_dispose.html#using-declaration)
- [Using 使い方は４種類](http://dotnetcsharptips.seesaa.net/article/444308697.html)
- [－usingを使え、使えったら使え(^^)－](https://divakk.co.jp/aoyagi/csharp_tips_using.html)
- [using ステートメント (C# リファレンス)](https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/keywords/using-statement)
- [using static ディレクティブ (C# リファレンス)](https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/keywords/using-static)