2016-04-26 2 views
0

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

var resource = CreateNewResource(); 

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

Первый тип:

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

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

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

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

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

+0

Разница заключается в том, чтобы удалить время экземпляра класса. При использовании блока экземпляр класса будет располагаться после выхода из блока. –

+0

@SiyavashHamdi: Я догадался, что много. Что происходит в первом стиле кодирования? Это просто поверхностно кодировать по первому стилю? Я видел этот стиль во многих местах. – displayName

+0

@SiyavashHamdi: Кроме того, что происходит с ресурсом в первом стиле? – displayName

ответ

5

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

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

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

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

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

+0

Хорошо. Очевидно, что первый стиль, который я видел в несколько мест плохо. – displayName

+0

@displayName Где вы его видели? В общедоступном коде или на рабочем месте? –

+0

@DStanley: Ой, я в ловушке. Не могу сказать, где я его видел. Догадка.: D – displayName

0

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

Довольно хорошо documented on MSDN:

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

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

+0

Если читаемость является проблемой, вы можете иметь символы новой строки в декларации 'use()' и поместить внутреннюю часть в отдельную строку. –

+0

@DStanley: Иногда вызов выглядит как 'var resource = CreateNewResourceByCallingALargeNamedMethod (abc, def, ghi, jklmnopqrstu, vwxyz);' Метод имеет длинное имя и принимает так много длинных именных аргументов. Visual Studio обертывает текст, разбивая его запятой. Там просто нет способа написать его, который можно прочитать. Его можно разбить на несколько строк, каждый из которых вводит собственную строку, но это излишне удлиняет используемый блок. – displayName

Смежные вопросы