コードブロックの途中でusing文が使われているのを見たことがありますが、その理由は何ですか?
の使う実装されているものすべてに対してスコープを定義する方法として構文を使用することができます(使用するべきです)。使い捨て。 usingステートメントは、例外が発生した場合にDisposeが確実に呼び出されるようにします。
//the compiler will create a local variable
//which will go out of scope outside this context
using (FileStream fs = new FileStream(file, FileMode.Open))
{
//do stuff
}
代わりにあなたはただ使用することができます:
FileStream fs;
try{
fs = new FileStream();
//do Stuff
}
finally{
if(fs!=null)
fs.Dispose();
}
C#は、.NET Framework共通言語ランタイム(CLR)を介して、不要になったオブジェクトを格納するために使用されていたメモリを自動的に解放します。メモリの解放は非決定的です。 CLRがガベージコレクションを実行することを決定するたびにメモリが解放されます。ただし、通常はファイルハンドルやネットワーク接続などの限られたリソースをできるだけ早く解放することをお勧めします。
usingステートメントを使用すると、プログラマはリソースを使用するオブジェクトがいつそれらを解放するかを指定できます。 usingステートメントに提供されるオブジェクトは、IDisposableインターフェイスを実装する必要があります。このインタフェースはDisposeメソッドを提供します。これはオブジェクトのリソースを解放します。
ストリームまたはデータベースへの接続を開くときによく使用されます。
これはtry {...} finally {...}ブロックのように動作します。後に使うblockの場合、括弧内にインスタンス化されたIDisposableオブジェクトは正しく閉じられます。
using (Stream stream = new Stream(...))
{
}
この例では、ブロックの後でストリームは正しく閉じられます。
sqlconnectionのようにIDisposableがあるものすべてに対して、usingを使用して最後に構文解析を試してください。それの使用はそれが何かがそれのうちの後に処分されることを確実にしますusing(){}
範囲。
using(SqlConnection conn = new SqlConnection(connString))
{
//use connection
}
//shorter than
SqlConnection conn = new SqlConnection(connString)
try
{
//use connection
}
finally
{
conn.Dispose();
}
usingステートメントは、不要になったオブジェクトが適切に破棄されるようにします。 基本的に、obj.Dispose()を書く手間が省けます。また、変数の範囲と使用法に関する視覚的なガイドを提供します。
見るMSDNページ詳しくは
この使用方法は、リソースの解放と関係があります。 IDisposableインターフェイスを実装するクラスと組み合わせてのみ使用できます。
例:
using(SqlConnection conn = new SqlConnection(someConnectionString))
{
//Do some database stuff here
}
ブロックの内側で例外がスローされた場合でも、使用中のブロックの最後でconn.Disposeが呼び出されます。 SwqlConnectionオブジェクトの場合は、接続が常に閉じられることを意味します。
この構造の欠点は、何が起こったのかを知る方法が今あることです。
これであなたの質問に答えることができますか?
あなたのコードがIDisposableを実装するオブジェクトを作成するときはいつでも、あなたのコードは上で見たようにusingブロックの中で作成をするべきです。
この規則には1つ例外があります。 WCFプロキシクラスの設計に誤りがあると、ステートメントの使用がプロキシクラスに役立つことを妨げます。簡単に言うと、プロキシクラスのDisposeメソッドは例外をスローする可能性があります。 WCFチームはこれを許可しない理由はありませんでした。
残念なことに、理由が見えないということはそれがあるという意味ではありませんです理由はありません。
try
{
using (var svc = new ServiceReference.ServiceName())
{
throw new Exception("Testing");
}
}
catch (Exception ex)
{
// What exception is caught here?
}
暗黙のDispose呼び出しが例外を投げるなら、catchブロックはcatchするでしょうそれ内でスローされた例外ではなく、例外使うブロック。