У меня есть несколько вопросов по поводу следующего кода:
using System;
namespace ConsoleApplication2
{
public struct Disposable : IDisposable
{
public void Dispose() { }
}
class Program
{
static void Main(string[] args)
{
using (Test()) { }
}
static Disposable Test()
{
return new Disposable();
}
}
}
Мои вопросы:
- Будет ли оператор using, работающий со структурой
Disposable
, возвращаемый из Test()
, содержать структуру или нет?
- Как я могу найти ответ сам?
Чтобы попытаться выяснить это самостоятельно, я проверил IL, созданный с помощью вышеуказанного кода, и вот IL для метода Main(...)
:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
.maxstack 1
.locals init (
[0] valuetype ConsoleApplication2.Disposable CS$3$0000)
L_0000: call valuetype ConsoleApplication2.Disposable ConsoleApplication2.Program::Test()
L_0005: stloc.0
L_0006: leave.s L_0016
L_0008: ldloca.s CS$3$0000
L_000a: constrained ConsoleApplication2.Disposable
L_0010: callvirt instance void [mscorlib]System.IDisposable::Dispose()
L_0015: endfinally
L_0016: ret
.try L_0006 to L_0008 finally handler L_0008 to L_0016
}
Я подозреваю, что вызов виртуального метода там, на L_0010
введет операцию упаковки, но фактической инструкции box
здесь нет.
Причина, по которой я спрашиваю, состоит в том, что некоторое время назад, возможно, 1-2 года, я увидел в сети «оптимизацию» заявления об использовании, которое кто-то прокомментировал. Был случай, когда оператор using был использован в качестве синтаксиса для кратковременной блокировки объекта, когда была получена блокировка в методе, и была возвращена структура, которая при удалении снимала блокировку, код, подобный этому :
using (LockTheObject())
{
// use the object
}
и комментарий состоял в том, что, изменив тип возвращаемого значения метода LockTheObject
с IDisposable
на фактическую используемую структуру, можно было избежать упаковки.
Но мне интересно, правда ли это или все еще правда.
Кто-нибудь может указать мне правильное направление? Если, чтобы увидеть работу блока, мне нужно будет проверить код сборки во время выполнения, пожалуйста, покажите мне пример того, что искать, я хорошо разбираюсь в коде сборки, так что это не проблема, но ничего не выпрыгнуло на меня, когда я смотрел на это тоже.