Disposeは引き続き呼び出されます。実行しているのは、変数_clientをメモリ内の他の何か(この場合はnull)にポイントすることだけです。_clientが最初に参照したオブジェクトは、usingステートメントの最後に引き続き破棄されます。
この例を実行します。
class Program
{
static Foo foo = null;
static void Main(string[] args)
{
foo = new Foo();
using (foo)
{
SomeAction();
}
Console.Read();
}
static void SomeAction()
{
foo = null;
}
}
class Foo : IDisposable
{
#region IDisposable Members
public void Dispose()
{
Console.WriteLine("disposing...");
}
#endregion
}
変数をnullに設定しても、オブジェクトが破壊されたり、を使用してオブジェクトが破棄されたりすることはありません。あなたがしているのは、最初に参照されたオブジェクトを変更するのではなく、変数の参照を変更することだけです。
後期編集:
リファレンスhttp://msdn.microsoft.com/en-us/library/yh598w02.aspxとOPのコードを使用した、MSDNに関するコメントからの議論に関して、私の例では、このようなコードのより単純なバージョンを作成しました。 。
Foo foo = new Foo();
using (foo)
{
foo = null;
}
(そして、はい、オブジェクトはまだ破棄されます。)
上記のリンクから、コードが次のように書き直されていることが推測できます。
Foo foo = new Foo();
{
try
{
foo = null;
}
finally
{
if (foo != null)
((IDisposable)foo).Dispose();
}
}
これはオブジェクトを破棄せず、コードスニペットの動作と一致しません。そこで、ildasmで調べました。収集できる最善の方法は、元の参照がメモリ内の新しいアドレスにコピーされていることです。ステートメントfoo = null;
は元の変数に適用されますが、への呼び出し.Dispose()
はコピーされたアドレスで発生しています。それで、コードが実際に書き直されていると私がどのように信じているかを見てみましょう。
Foo foo = new Foo();
{
Foo copyOfFoo = foo;
try
{
foo = null;
}
finally
{
if (copyOfFoo != null)
((IDisposable)copyOfFoo).Dispose();
}
}
参考までに、これはildasmを通してILがどのように見えるかです。
.method private hidebysig static void Main() cil managed
{
.entrypoint
// Code size 29 (0x1d)
.maxstack 1
.locals init ([0] class Foo foo,
[1] class Foo CS$3$0000)
IL_0000: newobj instance void Foo::.ctor()
IL_0005: stloc.0
IL_0006: ldloc.0
IL_0007: stloc.1
.try
{
IL_0008: ldnull
IL_0009: stloc.0
IL_000a: leave.s IL_0016
} // end .try
finally
{
IL_000c: ldloc.1
IL_000d: brfalse.s IL_0015
IL_000f: ldloc.1
IL_0010: callvirt instance void [mscorlib]System.IDisposable::Dispose()
IL_0015: endfinally
} // end handler
IL_0016: call int32 [mscorlib]System.Console::Read()
IL_001b: pop
IL_001c: ret
} // end of method Program::Main
私はildasmを見つめて生計を立てていないので、私の分析は警告の空虚として分類することができます。ただし、動作はそれが何であるかです。