Почему использование (ноль) допустимого регистра в C#?

Может ли кто-нибудь объяснить мне, почему приведенный ниже код действителен в C# и выполняет вызов Console.WriteLine?

using (null) 
{
   Console.WriteLine ("something is here")
}

Он компилируется в (наконец, блок показан). Как видите, компилятор решает не выполнять Dispose() метод и прыгает на endfinally инструкция.

IL_0013:  ldnull
IL_0014:  ceq
IL_0016:  stloc.1
IL_0017:  ldloc.1
IL_0018:  brtrue.s   IL_0021 // branches here and decide not to execute Dispose()
IL_001a:  ldnull
IL_001b:  callvirt   instance void [mscorlib]System.IDisposable::Dispose()
IL_0020:  nop
IL_0021:  endfinally

Тем не менее, если я запускаю следующий код, он потерпит неудачу с NullReferenceException (что ожидается):

((IDisposable)null).Dispose();
IL_0023:  ldnull
IL_0024:  callvirt   instance void [mscorlib]System.IDisposable::Dispose()

Почему первая версия компилируется? Почему компилятор решает не выполнять Dispose()? Есть ли другие случаи, когда компилятор может решить не вызывать Dispose() в using блок?

3 ответа

Спецификация языка в явном виде заявляет (8.13), что захваченное значение при необходимости проверяется на нулевое значение, т.е. finally по существу (с оговорками вокруг ненулевых типов)

if(tmp != null) tmp.Dispose();

Я часто использую это в своих интересах, для вещей, которые могут быть нулевыми, но когда это не так: нужно избавляться. На самом деле, вот полезный сценарий (перечисление вручную IEnumerable):

IEnumerable blah = ...; // note non-generic version
IEnumerator iter = blah.GetEnumerator();
using(iter as IDisposable)
{
    // loop
}

как неуниверсальная версия IEnumerator не обязательно IDisposable, но когда это так, следует утилизировать.

Я думаю, что это естественный результат более общего случая using(some_expression), где some_expression разрешено оцениватьnull,

Потребовалось бы специальное правило, чтобы отличить этот случай от более общего.

Он будет игнорировать, если объект является нулевым - http://msdn.microsoft.com/en-us/library/yh598w02.aspx

Другие вопросы по тегам