今回はC#で欠かせない存在のusing
の使い方を四つに分けて紹介したいと思います。
早速、始めていきましょう!
ディレクティブとしてのusing 見出しへのリンク
C#でusingと言えば最初に思い浮かべるであろう使い方は、やはりディレクティブとしてのusing
でしょう。
usingディレクティブと聞いてピンと来なかった方も以下のコードを見ればわかるはずです。
// これがディレクティブとしてのusing
using System;
このusing
は、異なる名前空間の中にあるモジュールを短い名前で呼び出す為に使用されます。
例えば、ファイルの読み書きをストリームで行いたいときに
System.Text.Encoding enc = System.Text.Encoding.GetEncoding("UTF8");
System.IO.StreamWriter writer = new System.IO.StreamWriter("./some_file.txt", false, enc);
と書くことはできますが、これでは余りにも冗長で可読性が低くなってしまいます。
こんな時こそusing
です。using
を使えば名前空間を省略できます。先ほどの例であれば
// ファイルの先頭にこれらを書く
using System.Text;
using System.IO;
// Before
System.Text.Encoding enc = System.Text.Encoding.GetEncoding("UTF8");
System.IO.StreamWriter writer = new System.IO.StreamWriter("./some_file.txt", false, enc);
// After
Encoding enc = Encoding.GetEncoding("UTF8");
StreamWriter writer = new StreamWriter("./some_file.txt", false, enc);
なんということでしょう。あんなに読みにくかったコードがこんなに簡潔に! (今回の内容とは関係ないですがvarを使うともっと読みやすくなります。)
忘れられがちなusing static 見出しへのリンク
先程のusing
の派生としてusing static
というものがあります。これは クラス名を省略できるようにする為に使われます。例をあげます。
// ファイルの先頭にこれを書く
using static System.Math;
// 半径10の円と同じ面積の正方形の一辺の長さを求めたい
// Before
double radius = 10d;
double ans = Math.Sqrt(radius * radius * Math.PI);
// After
double radius = 10d;
double ans = Sqrt(radius * radius * PI);
本来、Math.Sqrt
Math.PI
と書かなければならない所をこんなにも簡潔に書く事ができます。
using static
はその名前の通りstaticなメンバについてのみクラス名を省略できるようになります。
(そうでなかったら色々やばそうですが…)
因みにこの機能はあまり使わない印象です。使うのであればSystem.Math
かSystem.Console
位でしょうか。
名前を変えるusing 見出しへのリンク
ある日、caphosra君は以下のようなを実装しました。
namespace CapraLib
{
public class Random
{
// 乱数を出すよ(噓)
public int Next(int maxv)
{
return 0;
}
}
}
そして、以下のようなコードを書きました。
// ファイルの先頭にこれらを書く
using System;
using CapraLib;
// 51未満の乱数を出したい...がエラー
int rndVal = new Random().Next(51);
もうお分かりでしょう。これは上手く動きません。
ここで参照しているRandom
クラスはSystem.Random
でしょうか?それともCapraLib.Random
?
わかりませんね。
そこで登場するのが名前を変えるusing
です。
// これが名前を変えるusing
using CapRandom = CapraLib.Random;
using SystemRandom = System.Random;
// 51未満の乱数を出したい
// CapraLib.Randomの気分の時
int rndVal1 = new CapRandom().Next(51);
// System.Randomの気分の時
int rndVal2 = new SystemRandom().Next(51);
これで使い分けができます!
これはクラスに対して使っていますが、名前空間も同じように名前を変えられます。
// 短い名前に変えられますよ!
using GenericCol = System.Collections.Generic;
これでとても長い名前空間とおさらばです。
解放してくれるusing 見出しへのリンク
これは知っているのと知らないのでは大きく違います。
このusing
はリソース解放を忘れる事を防止する為に使われます。例を見ていきましょう。
using System.Text;
using System.IO;
Encoding enc = Encoding.GetEncoding("UTF8");
StreamWriter writer = new StreamWriter("./some_file.txt", false, enc);
writer.WriteLine("I wanna be one of the GREATEST programmers!");
// writer.Close(); 忘れてる
このコード、やばいですね。気付きにくいですが、writer
が解放されていません。
即ち、ファイルを開きっぱなしでコードが終わっています。開けたら閉めるが基本ですよね。writer
はClose()
という関数を持っているのでこれを最後に呼んであげればいいです、が…
この方法だと、とても忘れやすい!
そこでこの方法。
using System.Text;
using System.IO;
Encoding enc = Encoding.GetEncoding("UTF8");
using (StreamWriter writer = new StreamWriter("./some_file.txt", false, enc))
{
writer.WriteLine("I wanna be one of the GREATEST programmers!");
} // ここでwriter.Dispose()が呼ばれる
このusing
を使えば、中カッコ(スコープ)を抜けたときにDispose()
を呼んでくれます。StreamWriter
はClose()
でもDispose()
でも解放できますので、このコードは正常に動作します。黙っててすみません。
この記法のメリットは何と言っても、Dispose()
の呼び忘れが起こらない事じゃないでしょうか。
ついうっかり、でメモリリークすることがないのでこの記法を絶対に使用すべきです。使える時は。
このusing
が使えるのはクラスがIDisposable
を実装している時のみです。IDisposable
を実装しているのはStreamWriter
以外にも沢山あるので調べてみてください!
あと、自分のライブラリとかを作るときにIDisposable
を積極的に実装すれば、using
好きが沢山使ってくれるかも…?
[おまけ] C#8.0での解放する為のusing 見出しへのリンク
C#8.0で解放する為のusingに新たな記法が加わりました。 これを利用すると、以下のように書く事ができます。
using System.Text;
using System.IO;
Encoding enc = Encoding.GetEncoding("UTF8");
using StreamWriter writer = new StreamWriter("./some_file.txt", false, enc);
writer.WriteLine("I wanna be one of the GREATEST programmers!");
// スコープを抜けるとwriter.Dispose()が呼ばれる
変数の型の前に置いてあるusing
によって、writer
が寿命を迎えたときにDispose()
が呼ばれるようになります。
これはとてもcoolな記法ですね。ミスも防げます。
まとめ 見出しへのリンク
いかがだったでしょうか。この記事を読んで、C#のusingにもっと優しくしてあげようかな、と思っていただければ幸いです。でも正直using static使わないだろうなぁ