or操作using
を実行すると、ステートメントで作成されたオブジェクトが破棄されるのだろうか。以下に例を示します。return
throw
using(SomeClass thing = new SomeClass())
{
...
if(condition)
return;
...
}
上記は混乱しますか、それともGCはここで信頼されるべきですか?
or操作using
を実行すると、ステートメントで作成されたオブジェクトが破棄されるのだろうか。以下に例を示します。return
throw
using(SomeClass thing = new SomeClass())
{
...
if(condition)
return;
...
}
上記は混乱しますか、それともGCはここで信頼されるべきですか?
はい、そうなります。このusing
ステートメントにより、finally
ブロックが作成されます。関連するブロックfinally
で例外がスローされたtry
場合、またはreturn
その try ブロックにステートメントがある場合でも、ブロックのコードは実行されます。
ブロックのコードが実行されない原因となる例外はごくわずかでありfinally
、それらはすべてここにリストされていますが、あなたの状況では、それらの結果に耐えることができると思います.
usingステートメントを作成する場合:
using(SomeClass thing = new SomeClass())
{
//...
if (condition)
return;
//...
}
これにより、次のコードが生成されます。
SomeClass thing;
try
{
thing = new SomeClass();
//...
if (condition)
return;
//...
}
finally
{
if(thing != null)
{
thing.Dispose();
}
}
したがって、宣言using ( /* HERE */ )
されたすべてのオブジェクトは自動的に破棄されます。内部で宣言されたオブジェクトはし{}
ません。ただし、もちろん、ステートメントを使用してネスト(またはスタック)することができます。
using (var thing = new SomeClass())
using (var another = new Another())
using (var somethingElse = new Whatever())
{
//...
}
これはもちろん、書くための単なる構文糖衣です
using (var thing = new SomeClass())
{
using (var another = new Another())
{
using (var somethingElse = new Whatever())
{
//...
}
}
}
ステートメントの後にコードの1つのブロック(この場合は別のusing
ブロック)が続く場合、中括弧をスキップできます...
同じタイプの2つ以上のオブジェクトを使用する場合、using
ステートメント内で宣言を連鎖させることができます。
using (MemoryStream stream = new MemoryStream(), stream2 = new MemoryStream())
{
//...
}
(それを指摘してくれた@Gratzyに感謝します)
dispose が実装されている場合は、常に呼び出されます。これは、finally ブロックで dispose を呼び出すのと同じです。
はい、処分します。これにより、CIL コードに finally ブロックが作成されます。
はい、using はコンパイラによって try finally に拡張されるためです。Dispose は、finally ブロック内で発生します。また、finally には、using の変数が null かどうかをチェックするテストが含まれます (コンストラクターに例外がある場合)。
using
そうですtry-finally
、はい、そうです。