C#のUsingブロックの目的は何ですか?ローカル変数とどう違うのですか?
型がIDisposableを実装している場合は、自動的に破棄されます。
与えられた:
public class SomeDisposableType : IDisposable
{
...implmentation details...
}
これらは同等です:
SomeDisposableType t = new SomeDisposableType();
try {
OperateOnType(t);
}
finally {
if (t != null) {
((IDisposable)t).Dispose();
}
}
using (SomeDisposableType u = new SomeDisposableType()) {
OperateOnType(u);
}
2つ目は読みやすく維持しやすいです。
Using
は、コードが例外をスローしたとしても、using
-ブロックが残った後にDispose()
を呼び出します。
そのため、IOのように、後からクリーンアップする必要があるクラスには通常using
を使用します。
だから、これを使用してブロック:
using (MyClass mine = new MyClass())
{
mine.Action();
}
以下と同じことをします。
MyClass mine = new MyClass();
try
{
mine.Action();
}
finally
{
if (mine != null)
mine.Dispose();
}
using
を使用すると、ずっと短くなり、読みやすくなります。
MSDNから:
C#は、.NET Framework共通言語ランタイム(CLR)を介して、不要になったオブジェクトの格納に使用されているメモリを自動的に解放します。メモリの解放は非決定的です。 CLRがガベージコレクションを実行することを決定するたびにメモリが解放されます。ただし、通常はファイルハンドルやネットワーク接続などの限られたリソースをできるだけ早く解放することをお勧めします。
Usingステートメントを使用すると、プログラマはリソースを使用するオブジェクトがいつそれらを解放するかを指定できます。 usingステートメントに提供されるオブジェクトは、IDisposableインターフェイスを実装する必要があります。このインタフェースはDisposeメソッドを提供します。これはオブジェクトのリソースを解放します。
つまり、using
ステートメントは、using
ブロックで指定されたオブジェクトが不要になったら解放するように.NETに指示します。
Usingステートメントは、IDisposable
インターフェイスを実装するC#のオブジェクトを操作するために使用されます。
IDisposable
インターフェースには、オブジェクトの破棄に使用されるDispose
というパブリックメソッドが1つあります。 usingステートメントを使用するとき、コード内でオブジェクトを明示的に破棄する必要はありません。usingステートメントがそれを処理します。
using (SqlConnection conn = new SqlConnection())
{
}
上記のブロックを使用すると、内部的にコードは次のように生成されます。
SqlConnection conn = new SqlConnection()
try
{
}
finally
{
// calls the dispose method of the conn object
}
using (B a = new B())
{
DoSomethingWith(a);
}
と同等です
B a = new B();
try
{
DoSomethingWith(a);
}
finally
{
((IDisposable)a).Dispose();
}
using
によってインスタンス化されたオブジェクトは、usingブロック内では読み取り専用です。公式C#リファレンス こちら を参照してください。
Usingブロックにコードを配置すると、制御がブロックを離れるとすぐにオブジェクトが確実に破棄されます(ただし必ずしも収集されるわけではありません)。
Usingステートメントは1つ以上のリソースを取得し、ステートメントを実行してからリソースを破棄します。
IDisposableを実装しているメンバに対してDisposeを明示的に呼び出す必要がないのは、実際には単なる構文上の糖分です。