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 не уничтожает объект и не препятствует его удалению с помощью using. Все, что вы делаете, это изменяете ссылку на переменную, а не изменяете объект, на который изначально ссылались.
Позднее редактирование:
Что касается обсуждения из комментариев о 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();
}
}
Для справки, вот как выглядит IL через 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, поэтому мой анализ можно классифицировать как caveat emptor. Однако поведение то, что есть.
person
Anthony Pegram
schedule
25.03.2010