質問
可能な重複:
C#を使用するブロックとその理由使用すべきですか?
コードブロックの途中でusingステートメントが使用されているのを見ましたが、この理由は何ですか?
解決
using 構文は、 IDisposable 。 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 {...}ブロックのように動作します。 using ブロックの後、括弧でインスタンス化されたIDisposableオブジェクトは適切に閉じられます。
using (Stream stream = new Stream(...))
{
}
この例では、ブロックの後にストリームが適切に閉じられます。
usingは、sqlconnectionのようなIDisposable ..を持つものすべてに対して、最終的に構文上のシュガーを試すことです。その使用により、 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
}
ブロック内で例外がスローされた場合でも、usingブロック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ブロックは using ブロック内でスローされる例外ではなく、 that 例外をキャッチします。