Заголовок этого сообщения обескураживает, не правда ли? Тем не менее, вы достаточно сообразительны, чтобы догадаться, о чем пойдет речь. На собеседовании по .NET часто задают вопрос: ”Чем отличаются директива using и оператор using?” Иногда перед соискателем ставят дополнительные ловушки, спрашивая, в каких местах программы можно использовать using? Первое, что приходит в голову, это использование директивы using, которая применяется для определения или разрешения использования типов как пространств имен. Например, следующий фрагмент кода демонстрирует включение некоторых пространств имен с помощью директивы using.
Погодите! Это не всё! Есть нечто, называемое “директивой псевдонимов (aliasing directive)” и ее можно использовать, как показано в следующей строке кода. Это может быть промежуточной частью ответа на вопрос.
Теперь вернемся к оператору using, который задает область видимости, вне которой объект недоступен. Рассмотрим следующий пример:
Объект imageFrame определен с помощью блока using. Это означает, что когда выполнение блока кода завершиться, объект imageFrame больше не потребуется, и он может бытьуничтоженудален. Такой подход крайне важен для эффективного управления памятью.
using System.IO;
using System.Text;
Погодите! Это не всё! Есть нечто, называемое “директивой псевдонимов (aliasing directive)” и ее можно использовать, как показано в следующей строке кода. Это может быть промежуточной частью ответа на вопрос.
using mynamespace = myproject.module;
Теперь вернемся к оператору using, который задает область видимости, вне которой объект недоступен. Рассмотрим следующий пример:
using(ColorImageFrame imageFrame = e.OpenColorImageFrame())
{
// здесь ваш код
}
Объект imageFrame определен с помощью блока using. Это означает, что когда выполнение блока кода завершиться, объект imageFrame больше не потребуется, и он может быть
Комментарии (41)
IL_Agent
01.02.2016 16:22+18Заголовок этого сообщения обескураживает, не правда ли?
Да и содержимое «сообщения» тоже слегка :)
lair
Ладно бы вы просто написали тривиальную информацию, так вы же еще и ошиблись.
Нет такой вещи как «уничтожение объекта» в .net. Инструкция
using
всего лишь гарантирует (кстати, не на 100%) вызовDispose
(и одновременно ограничивает область видимости). Проще говоря, это синтаксический сахар вокругtry...finally
.А для того, чтобы задать область видимости,
using
вообще не нужен, достаточно блок объявить.Sing
> Проще говоря, это синтаксический сахар вокруг try...finally.
Не совсем. Он ещё делает объект доступным только для чтения.
> кстати, не на 100%
А когда не гарантирует? Или вы о случае, когда объект инициируется в null?
DrReiz
Что означает фраза «делает объект доступным только для чтения»?
Sing
> Within the using block, the object is read-only and cannot be modified or reassigned.
https://msdn.microsoft.com/en-US/library/yh598w02.aspx
DrReiz
В документации опечатка. Вместо слова 'object' подразумевается слово 'variable'.
Соответственно: переменная, объявленная в using, не может быть переприсвоена. На сам объект никаких ограничений не накладывается.
Sing
В чём опечатка? В .NET все переменные — это объекты.
lair
Семантически, ошибка в том, что объект, на который ссылается переменная, может быть как угодно изменен (поэтому объект не read-only), однако никакая другая ссылка переменной быть присвоена не может (поэтому переменная — read-only).
DrReiz
Переменная и объект — это две разные сущности. Несколько переменных могут ссылаться на один объект, одна переменная может ссылаться на разные объекты (в разные моменты времени).
Переменная — это ссылка на объект, размещается в стеке.
Объект — это область памяти, хранящая данные объекта. Размещается в хипе.
ps
За скобкам оставлен вариант с value-типами.
DrReiz
Изменение переменной не меняет объект. Изменение объекта не меняет переменную.
Sing
Да, точно, моя ошибка.
Структуры в using изменять не получится, т.е. в этом случае и объект тоже read-only.
lair
Это следствие того же синтаксического сахара.
Если по каким-то причинам случилось исключение после присвоения, но до входа в
try
(например, ThreadAbort). Или, что более занятно, если вы используете using вместе с object initializer (кстати, мне интересно, не поменяли ли это поведение после C# 4).a553
Не поменяли.
aikixd
Какой тогда смысл использовать using, а не try?
lair
Во-первых,
using
лучше показывает ваше намерение.Во-вторых, у вас меньше шансов допустить какую-нибудь глупую ошибку в реализации.
(ну и в-третьих, это занимает ощутимо меньше кода)
imanushin
Один простой способ, но очевидный:
CompositeDisposable
Если упадет ошибка при создании второй транзакции, то объект под using'ом не будет создан. С try-finally произойдет ровно то же самое, магии тут нет.
Есть еще простой способ не вызвать Dispose — см. ниже разницу в наличии await. Класс Task реализует IDisposable, кстати )