web-dev-qa-db-ja.com

「using」ステートメントは常にオブジェクトを破棄しますか?

usingステートメントは、オブジェクト内に戻りがあるか例外がスローされた場合でも、常にオブジェクトを破棄しますか? I.E .:

using (var myClassInstance = new MyClass())
{
    // ...
    return;
}

または

using (var myClassInstance = new MyClass())
{
    // ...
    throw new UnexplainedAndAnnoyingException();
}
26

はい、それがすべてのポイントです。それは以下にコンパイルされます:

_SomeDisposableType obj = new SomeDisposableType();
try
{
    // use obj
}
finally
{
    if (obj != null) 
        ((IDisposable)obj).Dispose();
}
_

ここでの用語に注意してください。オブジェクト自体は割り当て解除されません。 Dispose()メソッドが呼び出され、通常、アンマネージリソースが解放されます。

32
Ed S.

オブジェクトがIDisposableを実装している場合、それが呼び出されます。

MSDNによるステートメント(C#リファレンス)の使用から

スコープを定義します。スコープの外側にはオブジェクトが配置されます。

Usingステートメントを使用すると、プログラマは、リソースを使用するオブジェクトが解放するタイミングを指定できます。 usingステートメントに提供されるオブジェクトは、IDisposableインターフェイスを実装する必要があります。このインターフェイスは、オブジェクトのリソースを解放するDisposeメソッドを提供します。

10
Adriaan Stander

いいえ、ありません。

しかし、それはusingステートメントのfaultではありません。これは、finallyブロックがCLRによってどのように処理されるかによるものです。 finallyブロックが実行されない場合があります。未処理の例外があり、CLRより多くのコードを実行すると、より多くのエラーが発生すると、Disposeメソッドは実行されません(finallyメソッドがコンパイルされたDisposeブロックを実行しないためです。)したがって、非常に注意して、Disposeメソッドの実行に命をかけないでください。

Disposeメソッドが実行されない原因となる可能性がある他のケースは、次のようにリストされます。

  • Environment.FailFast

  • OutOfMemoryExceptionおよびStackOverflowException

  • プロセスを強制終了する

  • 電力損失

5
sotn