Dispose все равно будет вызываться. Все, что вы делаете, указывает на переменную _client на что-то другое в памяти (в данном случае: null). Объект, который ссылается на _client, все еще будет удален в конце инструкции using.
Запустить этот пример.
Установка переменной в нуль не разрушает объект или препятствует его удалению путем использования. Все, что вы делаете, это изменение ссылки на переменную, а не изменение исходного объекта.
Late редактировать:
Что касается обсуждения от комментариев по поводу MSDN, используя ссылку http://msdn.microsoft.com/en-us/library/yh598w02.aspx и код в OP и в моем примере, я создал простую версию кода, как это.
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.
.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, так что мой анализ может быть классифицирован как РИСКОВАННАЯ ПОКУПКА. Однако поведение - это то, что есть.
Извините, но нисходящее голосование неверно. Но, хорошо, перепишите его. Моя точка зрения все еще стоит. Я отправлю код, соответствующий его примеру, если это поможет. –
@Ben, спасибо за повторное рассмотрение. ;) –
Ну, ваш первый пример был явно неправильным. Но так был и мой второй комментарий (который я удалил). :-) В моей защите ссылка немного вводит в заблуждение - http://msdn.microsoft.com/en-us/library/yh598w02.aspx; см. часть 'if (var! = null)', но я ее протестировал, и вы правы. –