Javaではパッケージ、他クラス使うとかでimportを使います。
C#では名前空間、他クラス使うとかではusingを使います。
JavaとかC#とか(他は知らないw)にあるGC。
使い終わったオブジェクトを破棄してくれる優れもの。
初めて聞いたときはすごいじゃん!とか思ってたら
いつか破棄してくれる
という事に笑った記憶があるGCです。
例えば
Sample s = new Sample(); //処理 s = null;
こんな感じでnullを代入して誰からも参照されなくなった時とか
public void Sample() { Sample s = new Sample(); //処理 }
こんな感じでnullは入れてないけどスコープを抜けた時とか
このような時にGCさんが重い腰を上げてくれますね
いつか
ではこのような場合はどうだろうか
public void FileUp() { FileStream fs = new FileStream("ファイルパス", FileMode.Open, FileAccess.Read, FileShare.None); StreamReader sr = new StreamReader(fs); Console.WriteLine(sr.ReadToEnd()); }
スコープから抜けるからGCさんの獲物になりそうな予感がします。
ただ、このストリームは閉じられていません。
なのでこのテキストファイルはGCさんが働いてくれないとずっと開きっぱなしになります。(この例だと、開きっぱなしなので他の人もオープンできない)
StreamReaderクラスのClose()を使ってしっかり閉めてあげないといけません。
そもそもJavaでもトイレの扉でも開けたら閉めるのは常識ですね。
閉めるだけのClose()ではなく便利なものがあります。
IDisposableインターフェースの使い終わったリソースを解放するためのDispose()というメソッドがあります。
Close()ではなくDispose()ひとつでOKです。
使い方としては
public void FileUp() { FileStream fs = new FileStream("ファイルパス", FileMode.Read); try { StreamReader sr = new StreamReader(fs); try { //処理 sr.Dispose(); fs.Dispose(); } catch () { //例外処理 } } catch () { //例外処理 } }
Close()の代わりに使う感じですね。
ただこの例だと、処理の時に例外が発生してしまった場合にDispose()を通りません。
なのでfinallyブロックを作ってあげることが必須です。
public void FileUp() { FileStream fs = new FileStream("ファイルパス", FileMode.Read); try { StreamReader sr = new StreamReader(fs); try { //処理 } catch () { //例外処理 } finally { if (sr != null) { sr.Dispose(); } } } catch () { //例外処理 } finally { if (fs != null) { fs.Dispose(); } } }
こんな感じですね、大したこと書いてないのにただ高さがありますね。
ここで本題なのですが、C#には自動でDispose()してくれる
using
というのがあります。Javaでいうtry-with-resourcesみたいな
先ほどの例を変えてみると。。。
public void FileUp() { using (FileStream fs = new FileStream("ファイルパス", FileMode.Read)) { using (StreamReader sr = new StreamReader(fs)) { try { //処理 } catch () { //例外処理 } } } }
こんな感じで半分になりました!自動的にfinallyでDispose()してくれます。
便利。
ただ、インポートする時にusing使ってるんだから違うキーワードにしてくれても良いのに・・・
と思った愚痴の記事でした。
コメント