私は次のコードを持っています
using(MemoryStream ms = new MemoryStream())
{
//code
return 0;
}
dispose()この方法は、の終了時に呼び出されるusing文のかっこ}右?I以来 returnの終了前にusing声明、うMemoryStreamオブジェクトが適切に配置されても?そこで何が起こるの?
私は次のコードを持っています
using(MemoryStream ms = new MemoryStream())
{
//code
return 0;
}
dispose()この方法は、の終了時に呼び出されるusing文のかっこ}右?I以来 returnの終了前にusing声明、うMemoryStreamオブジェクトが適切に配置されても?そこで何が起こるの?
回答:
はい、Dispose呼ばれます。実行が範囲外になるとすぐに呼び出されますusingブロックの終了、returnステートメント、または例外など、ブロックを離れるのにどのような意味があるかに関係なくブロックます。
@Noldorinが正しく指摘しているusingように、コードでブロックを使用すると、ブロックで呼び出されてtry/ finallyにコンパイルされます。たとえば、次のコード:Disposefinally
using(MemoryStream ms = new MemoryStream())
{
//code
return 0;
}
効果的に:
MemoryStream ms = new MemoryStream();
try
{
// code
return 0;
}
finally
{
ms.Dispose();
}
だから、finally後に実行されることが保証されているのでtry実行パスに関係なくブロックの実行が終了した、Disposeが必ずされるため、何が呼び出されても保証されます。
詳細については、このMSDNの記事を参照してください。。
補遺:
追加する際の注意点:Disposeは必ず呼び出されることが保証されているためDispose、を実装するときに例外がスローされないようにすることをお勧めしますIDisposable。残念ながら、コアライブラリにはいくつかのクラスがありますません、特定の状況下で投げるDispose私はあなたを見てる、WCFサービス参照/クライアントプロキシ-と呼ばれているが!-その場合Dispose、元の例外がDispose呼び出しによって生成された新しい例外のために飲み込まれるため、例外スタックのアンワインド中に呼び出された場合、元の例外を追跡することは非常に困難です。それは手に負えないほどイライラすることがあります。それともイライラさせられますか?2つのうちの1つ。多分両方。
Disposeinの呼び出しでtry-finallyブロックに効果的にコンパイルされているので、説明したように、の実装が効果的に機能していることがわかりfinallyます。
usingステートメントはtry ... finallyブロックとまったく同じように動作するため、常にコード終了パスで実行されます。ただし、finallyブロックが呼び出されない非常にまれな状況の影響を受けると思います。私が覚えている1つの例は、バックグラウンドスレッドがアクティブなときにフォアグラウンドスレッドが終了した場合です。GCを除くすべてのスレッドが一時停止され、finallyブロックは実行されません。
明らかな編集: IDisposableオブジェクトを処理するロジックを除いて、それらは同じように動作します。
ボーナスコンテンツ:スタックできます(タイプが異なる場合):
using (SqlConnection conn = new SqlConnection("string"))
using (SqlCommand comm = new SqlCommand("", conn))
{
}
また、コンマ区切り(タイプは同じ):
using (SqlCommand comm = new SqlCommand("", conn),
SqlCommand comm2 = new SqlCommand("", conn))
{
}
using声明、オブジェクトにかかわらず、完了パスの処分されます。
参考文献...