Создание ресурса в блоке использования против блока использования

Например, свежий экземпляр одноразового ресурса может быть создан с помощью:

var resource = CreateNewResource();

В чем разница, если таковая имеется, в следующих стилях кодирования?

Первый Стиль:

var resource = CreateNewResource();
using (resource)
{
    //Use resource
}

Второй стиль:

using (var resource = CreateNewResource())
{
    //Use resource
}

Является ли первый стиль плохой практикой кодирования, если мы не собираемся использовать ресурс где-либо за пределами блока using?

Даже если мы хотим использовать ресурс вне блока использования, следует ли поощрять это желание использовать одноразовый ресурс вне блока использования?

2 ответа

Решение

Первое примечательное отличие состоит в том, что в вашем первом фрагменте переменный ресурс по-прежнему объявляется после блока using, и поэтому кто-то может использовать его после его удаления, что плохо.

var resource = CreateNewResource();
using (resource)
{
    //Use resource
}
...
// Unknowingly continues to use resource
resource.BadActOnDisposedObject();

Если вы решительно хотите использовать и распределять свои ресурсы более свободно, я бы предложил использовать try/finally, например так:

Resource resource = null;
try
{
    // do whatever
    resource = CreateNewResource();
    // continue to do whatever
}
finally
{
    if (resource != null)
    {
        resource.Dispose();
        resource = null;
    }
}

Это гарантирует, что ваш ресурс будет уничтожен в любом случае.

Хорошо.. так что это явно плохая практика.

Довольно хорошо задокументировано на MSDN:

Вы можете создать экземпляр объекта ресурса и затем передать переменную в оператор using, но это не лучший метод. В этом случае объект остается в области действия после того, как элемент управления покидает блок using, хотя, вероятно, он больше не будет иметь доступа к своим неуправляемым ресурсам. Другими словами, он больше не будет полностью инициализирован. Если вы попытаетесь использовать объект вне блока using, вы рискуете вызвать исключение. По этой причине, как правило, лучше создавать экземпляр объекта в операторе using и ограничивать его область применения блоком using.

Я видел этот стиль где-то в Интернете. В моем собственном коде всякий раз, когда оператор объявления ресурса в стиле 2 был очень длинным, я извлекал объявление из using(){} а затем написал код, упомянутый в стиле 1, чтобы сделать код более читабельным.

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