212

この質問にはすでに答えがあります。

C#のUsingブロックの目的は何ですか?ローカル変数とどう違うのですか?

9 답변


262

型が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つ目は読みやすく維持しやすいです。


  • 一般にfinallyブロックはDisposeを呼び出す前にnullをチェックすることに注意してください。コンストラクタを呼び出すときに問題になるわけではありませんが、... - Jon Skeet
  • usingブロックの外側で変数を宣言してからusingステートメントで新しいインスタンスを作成すると、アイテムが破棄されないことがあります。 - John
  • それで、using文はその文脈が完成したら自動的にオブジェクトを破棄します、IDisposableを実装する型でusing文をいつ使うべきですか?どのインターフェースがそのインターフェースを実装しなければなりませんか。これに関して何らかの経験則がありますか、それとも各タイプを個別にチェックする必要がありますか? - JsonStatham
  • ペダントであるため、限られた範囲を反映するために2番目のコードブロックを中括弧で囲む必要があります。 - Caltor
  • 注意:使用に気をつけろusingとブロックHttpClient()!見るこの記事。 - jbyrd

90

Using呼び出しDispose()後にusingコードが例外をスローしても、-blockは残ります。

だからあなたは通常使うusingIOのように、後から後始末を必要とするクラスのために。

だから、これを使用してブロック:

using (MyClass mine = new MyClass())
{
  mine.Action();
}

以下と同じことをします。

MyClass mine = new MyClass();
try
{
  mine.Action();
}
finally
{
  if (mine != null)
    mine.Dispose();
}

を使うusingずっと短くて読みやすいです。


  • nullチェックは必要ですか? new MyClass()の後、どのようにしてnullにすることができますか。私が見ることができる唯一のものはOutOfMemoryExceptionですが、その場合はtryブロックを正しく入力してはいけません。編集:あなたはおそらくusingが使われたときに通常行われることを示すためにこれを書きました。 usingの中には、新しいコンストラクタ呼び出し以外のものがあるかもしれません(例:nullを返すメソッド呼び出し) - tigrou
  • まあ、あなたは他のことができるmine.Action()。好きなものmine=null。地雷を使わずにtry / catchの中で何にでも設定できる - Sam

39

MSDNから:

.NET Framework共通によるC#   言語ランタイム(CLR)、自動的に   格納に使用されていたメモリを解放します。   不要になったオブジェクト   メモリの解放は   非決定論的メモリが解放されました   CLRが演じることを決心するときはいつでも   ガベージコレクションしかし、それは   通常はリリースを制限するのがベスト   ファイルハンドルなどのリソース   ネットワーク接続   可能。

usingステートメントは、   いつオブジェクトを指定するかプログラマ   リソースを使用している人は解放する   それら。使用に供されたオブジェクト   ステートメントは実装する必要があります   使い捨てインターフェース。このインターフェース   Disposeメソッドを提供します。   オブジェクトのリソースを解放する必要があります。

言い換えれば、usingステートメントは、.NETに、で指定されたオブジェクトを解放するように指示します。using不要になったらブロックします。


  • @plinthはそれが実際に何をするのかを示しながら、これは" using"を使うことの理論的根拠を与えます。 - tvanfosson
  • 確かに。これが、「C#のUsingブロックの目的は何ですか?」に対する回答です。 - Robert S.
  • @tvanfosson:FYI、アンパサンド文字は、このコメントの冒頭で行ったように、あなたがあなたのコメントをユーザーに向けていることを意味することを意味しています。あなたが台座について言及したときに行ったように、あなたはこの文字を他のユーザへのすべての参照に接頭辞を付ける必要はない。 - raven
  • @raven:ちなみに、'はアンパサンドではありません。 :) - Scott Ferguson

19

usingステートメントは、C#でオブジェクトを実装するオブジェクトを操作するために使用されます。IDisposableインタフェース。

IDisposableインターフェースには1つのパブリックメソッドがありますDisposeそれはオブジェクトを処分するために使用されます。 usingステートメントを使用するとき、コード内でオブジェクトを明示的に破棄する必要はありません。usingステートメントがそれを処理します。

using (SqlConnection conn = new SqlConnection())
{

}

上記のブロックを使用すると、内部的にコードは次のように生成されます。

SqlConnection conn = new SqlConnection() 
try
{

}
finally
{
    // calls the dispose method of the conn object
}

詳細については読んでください:C#のusingステートメントを理解する


5

usingブロックにコードを配置すると、制御がブロックを離れるとすぐにオブジェクトが確実に破棄されます(ただし必ずしも収集されるわけではありません)。


5

また、オブジェクトは次のようにインスタンス化されています。usingusingブロック内では読み取り専用です。公式のC#リファレンスを参照してください。ここに


5

using (B a = new B())
{
   DoSomethingWith(a);
}

と同等です

B a = new B();
try
{
  DoSomethingWith(a);
}
finally
{
   ((IDisposable)a).Dispose();
}


  • この答えには間違いが含まれています。 (そして、それが私たちのクラスに最初から正しく名前を付ける理由のもう一つの例です。)他の答えこの記事では。 - RayLuo

2

IDisposableを実装しているメンバーに対してDisposeを明示的に呼び出す必要がないのは、実際には単なる合成糖です。


2

usingステートメントは、1つ以上のリソースを取得し、ステートメントを実行してからリソースを破棄します。

リンクされた質問


関連する質問

最近の質問