Using c что это
Перейти к содержимому

Using c что это

Оператор using (справочник по C#)

Предоставляет удобный синтаксис, обеспечивающий правильное использование объектов IDisposable. Начиная с C# 8.0 инструкция using гарантирует правильное использование объектов IAsyncDisposable.

Пример

В следующем примере показано использование оператора using .

Для объявления using, представленного в C# 8.0, не требуются фигурные скобки:

Примечания

File и Font представляют собой примеры управляемых типов, которые обращаются к неуправляемым ресурсам (в данном случае это обработчики файлов и контексты устройств). Существуют и многие другие виды неуправляемых ресурсов и типов библиотек классов, которые их инкапсулируют. Все эти типы должны реализовывать интерфейс IDisposable или интерфейс IAsyncDisposable.

Когда время существования объекта IDisposable ограничено одним методом, необходимо объявить его и создать его экземпляр в операторе using или объявлении using . Объявление using вызывает для объекта метод Dispose надлежащим образом, когда он выходит за пределы области. Оператор using заставляет объект выходить за пределы области при вызове Dispose. В блоке using объект доступен только для чтения, и изменить или переназначить его невозможно. Переменная, объявленная с объявлением using , доступна только для чтения. Если объект реализует IAsyncDisposable вместо IDisposable , то любая форма using вызывает DisposeAsync и awaits возвращенный ValueTask. Дополнительные сведения о IAsyncDisposable см. в статье IAsyncDisposable.

Обе формы using обеспечивают вызов Dispose (или DisposeAsync), даже если в блоке using возникает исключение. Тот же результат можно получить, поместив объект в блок try , а затем вызвав Dispose (или DisposeAsync) в блоке finally , фактически компилятор переводит инструкцию using и объявление using именно так. Во время компиляции представленный выше код разворачивается в следующий (обратите внимание на дополнительные фигурные скобки, создающие ограниченную область действия для объекта):

Новый синтаксис инструкции using преобразуется в похожий код. Блок try открывается там, где объявлена переменная. Блок finally добавляется в конец охватывающего блока, как правило, в конце метода.

Дополнительные сведения об инструкции try — finally см. в описании try .

В одной инструкции using можно объявить сразу несколько экземпляров типа, как показано в следующем примере. Обратите внимание, что невозможно использовать неявно типизированные переменные ( var ) при объявлении нескольких переменных в одной инструкции:

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

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

Дополнительные сведения об утилизации объектов IDisposable см. в разделе IDisposable .

Спецификация языка C#

Дополнительные сведения см. в разделе Оператор using в статье Спецификации языка C#. Спецификация языка является предписывающим источником информации о синтаксисе и использовании языка C#.

8.6.3. Using-директивы

Пространства имен появились в стандартном С++. Предыдущие версии С++ их не поддерживали, и, следовательно, поставляемые библиотеки не помещали глобальные объявления в пространства имен. Множество программ на С++ было написано еще до того, как компиляторы стали поддерживать такую опцию. Заключая содержимое библиотеки в пространство имен, мы можем испортить старое приложение, использующее ее предыдущие версии: все имена из этой библиотеки становятся квалифицированными, т.е. должны включать имя пространства вместе с оператором разрешения области видимости. Те приложения, в которых эти имена употребляются в неквалифицированной форме, перестают компилироваться.

Сделать видимыми имена из библиотеки, используемой в нашей программе, можно с помощью using-объявления. Предположим, что файл primer.h содержит интерфейс новой версии библиотеки, в котором глобальные объявления помещены в пространство имен cplusplus_primer. Нужно заставить нашу программу работать с новой библиотекой. Два using-объявления сделают видимыми имена класса matrix и функции inverse() из пространства cplusplus_primer:

// using-объявления позволяют использовать

// имена matrix и inverse без спецификации

void func( matrix m ) <

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

Using-директива начинается ключевым словом using, за которым следует ключевое слово namespace, а затем имя некоторого пространства имен. Это имя должно ссылаться на определенное ранее пространство, иначе компилятор выдаст ошибку. Using-директива позволяет сделать все имена из этого пространства видимыми в неквалифицированной форме.

Например, предыдущий фрагмент кода может быть переписан так:

// using-директива: все члены cplusplus_primer

using namespace cplusplus_primer;

// имена matrix и inverse можно использовать без спецификации

void func( matrix m ) <

Using-директива делает имена членов пространства имен видимыми за его пределами, в том месте, где она использована. Например, приведенная using-директива создает иллюзию того, что все члены cplusplus_primer объявлены в глобальной области видимости перед определением func(). При этом члены пространства имен не получают локальных псевдонимов, а как бы перемещаются в новую область видимости. Код

для фрагмента программы, содержащего в области видимости следующую using-директиву:

using namespace A;

Рассмотрим пример, позволяющий подчеркнуть разницу между using-объявлением (которое сохраняет пространство имен, но создает ассоциированные с его членами локальные синонимы) и using-директивой (которая полностью удаляет границы пространства имен).

int bi = 16, bj = 15, bk = 23;

using namespace blip; // using-директива —

// коллизия имен ::bj and blip::bj

// обнаруживается только при

++bj; // ошибка: неоднозначность

// глобальная bj или blip::bj?

++::bj; // правильно: глобальная bj == 1

++blip::bj; // правильно: blip::bj == 16

int bk = 97; // локальная bk скрывает blip::bk

++bk; // локальная bk == 98

Во-первых, using-директивы имеют область видимости. Такая директива в функции manip() относится только к блоку этой функции. Для manip() члены пространства имен blip выглядят так, как будто они объявлены в глобальной области видимости, а следовательно, можно использовать их неквалифицированные имена. Вне этой функции необходимо употреблять квалифицированные.

Во-вторых, ошибки неоднозначности, вызванные применением using-директивы, обнаруживают себя при реальном обращении к такому имени, а не при встрече в тексте самой этой директивы. Например, переменная bj, член пространства blib, выглядит для manip() как объявленная в глобальной области видимости, вне blip. Однако в глобальной области уже есть такая переменная. Возникает неоднозначность имени bj в функции manip(): оно относится и к глобальной переменной, и к члену пространства blip. Ошибка проявляется только при упоминании bj в функции manip(). Если бы это имя вообще не использовалось в manip(), коллизия не проявилась бы.

В-третьих, using-директива не затрагивает употребление квалифицированных имен. Когда в manip() упоминается ::bj, имеется в виду переменная из глобальной области видимости, а blip::bj обозначает переменную из пространства имен blip.

И наконец члены пространства blip выглядят для функции manip() так, как будто они объявлены в глобальной области видимости. Это означает, что локальные объявления внутри manip() могут скрывать имена членов пространства blip. Локальная переменная bk скрывает blip::bk. Ссылка на bk внутри manip() не является неоднозначной – речь идет о локальной переменной.

Using-директивы использовать очень просто: стоит написать одну такую директиву, и все члены пространства имен сразу становятся видимыми. Однако чрезмерное увлечение ими возвращает нас к старой проблеме засорения глобального пространства имен:

using namespace cplusplus_primer;

using namespace DisneyFeatureAnimation;

matrix m; //ошибка, неоднозначность:

// cplusplus_primer::matrix или DisneyFeatureAnimation::matrix?

Ошибки неоднозначности, вызываемые using-директивой, обнаруживаются только в момент использования. В данном случае – при употреблении имени matrix. Такая ошибка, найденная не сразу, может стать сюрпризом: заголовочные файлы не менялись и никаких новых объявлений в программу добавлено не было. Ошибка появилась после того, как мы решили воспользоваться новыми средствами из библиотеки.

Using-директивы очень полезны при переводе приложений на новые версии библиотек, использующие пространства имен. Однако употребление большого числа using-директив возвращает нас к проблеме засорения глобального пространства имен. Эту проблему можно свести к минимуму, если заменить using-директивы более селективными using-объявлениями. Ошибки неоднозначности, вызываемые ими, обнаруживаются в момент объявления. Мы рекомендуем пользоваться using-объявлениями, а не using-директивами, чтобы избежать засорения глобального пространства имен в своей программе.

Читайте также

Использование директивы typedef

Использование директивы typedef Разработчики ядра не любят определять новые типы с помощью оператора typedef, и причины этого довольно трудно объяснить. Разумное объяснение может быть следующим.• Определение нового типа через оператор typedef скрывает истинный вид структур

9.3.1. HTTP-директивы

9.3.1. HTTP-директивы При подключении к Интернету пользователи первым делом стремятся загрузить Web-страничку. Если используется proxy, то необходимо правильно настроить HTTP-протокол. Для решения этой задачи в squid есть следующие директивы:? http_port n — параметр n определяет номер

10.3.4. Информационные директивы

10.3.4. Информационные директивы Эти директивы отвечают за информационные сообщения, которые видит пользователь, работая с вашим FTP-сервером:? banner имя — в качестве имени можно указать текстовый файл, содержимое которого будет передано пользователю во время входа в систему.

16.3.1. Общие директивы

16.3.1. Общие директивы Общие директивы изменяют глобальные параметры сервера — его имя, тип, порт, адрес администратора. Значения, указанные глобальными директивами, влияют на работу всего сервера.? ServerName — директива, которая определяет имя сервера Apache. Здесь должно быть

16.3.2. Директивы протоколирования

16.3.2. Директивы протоколирования Директивы протоколирования управляют процессом протоколирования работы сервера. С их помощью вы можете определить, что нужно записывать в журналы, а что — нет.? HostnameLookups on | off. Сервер Apache ведет журнал доступа других компьютеров. Если вы

16.3.9. Директивы перенаправления

16.3.9. Директивы перенаправления Довольно часто нужно перенаправить пользователя на другой ресурс: например, вы сменили хостера и из-за этого изменилось имя вашего сайта. Обычно при таком «переезде» у вас есть определенное время, чтобы сообщить вашим пользователям об

16.3.10. Директивы обработки ошибок

16.3.10. Директивы обработки ошибок Такая директива всего одна, но она очень полезна. Например, произошла ошибка 404 (файл не найден). Вы можете сопоставить этой ошибке URL, на который будет перенаправлен браузер пользователя. Обычно перенаправление устанавливают на документ,

3. Директивы сегментации

3. Директивы сегментации В ходе предыдущего обсуждения мы выяснили все основные правила записи команд и операндов в программе на ассемблере. Открытым остался вопрос о том, как правильно оформить последовательность команд, чтобы транслятор мог их обработать, а

17. Директивы препроцессора

17. Директивы препроцессора Директивы препроцессора – это особые инструкции, которые записаны в тексте программы на СИ и выполнены до трансляции программы. Директивы препроцессора дают возможность изменить текст программы. Среди таких действий – замена некоторых

Директивы препроцессора C#

Директивы препроцессора C# Подобно многим другим языкам из семейства C, в C# поддерживаются различные символы, позволяющие влиять на процесс компиляции. Перед рассмотрением директив препроцессора C# согласуем соответствующую терминологию. Термин "директива препроцессора

Директивы и атрибуты CIL

Директивы и атрибуты CIL Теперь, когда вы знаете, как использовать ildasm.exe и ilasm.exe в рамках челночной технологии разработки, мы можем заняться непосредственным анализом синтаксиса и семантики CIL. Следующие разделы предлагают описание процесса построения пользовательского

Директивы #if, #elif, #else, #endif

Директивы #if, #elif, #else, #endif Синтаксис:#if &lt;ограниченное-константное-выражение&gt; [&lt;текст&gt;][#elif &lt;ограниченное-константное-выражение&gt; &lt;текст&gt;][#elif &lt;ограниченное-константное-выражение&gt; &lt;текст&gt;][#else &lt;текст&gt;]#endifДиректива #if совместно с директивами #elif, #else и #endif

Директивы #ifdef и #ifndef

Директивы #ifdef и #ifndef Синтаксис:#ifdef &lt;идентификатор&gt;#ifndef &lt;идентификатор&gt;Аналогично директиве #if, за директивами #ifdef и #ifndef может следовать набор директив #elif и директива #else. Набор должен быть завершен директивой #endif.Использование директив #ifdef и #ifndef эквивалентно

1.3. Директивы препроцессора

1.3. Директивы препроцессора Заголовочные файлы включаются в текст программы с помощью директивы препроцессора #include. Директивы препроцессора начинаются со знака "диез" (#), который должен быть самым первым символом строки. Программа, которая обрабатывает эти директивы,

8.6.3. Using-директивы

8.6.3. Using-директивы Пространства имен появились в стандартном С++. Предыдущие версии С++ их не поддерживали, и, следовательно, поставляемые библиотеки не помещали глобальные объявления в пространства имен. Множество программ на С++ было написано еще до того, как

49. Директивы сегментации

49. Директивы сегментации Сегментация является частью более общего механизма, связанного с концепцией модульного программирования. Она предполагает унификацию оформления объектных модулей, создаваемых компилятором, в том числе с разных языков программирования. Это

What does using mean in c++?

In fact it’s a question inspired by the comment under this question:

5 Answers 5

This is called using declaration. There are actually two ways you can use the using keyword. There is a third special form of using declarations used inside class definitions, but i’ll focus on the general using declaration here. (see below).

  • using declaration
  • using directive

These have two very different effects. A using declaration declares a name to be an alias to another declaration or a set of declarations (if you were to name a set of overloaded functions). The name is declared in the current scope. That is, you can use it inside blocks too

This is quite useful if you use a name very often locally and you don’t want to prefix it in all uses, and it’s also useful in implementing the swap using argment dependent lookup idiom.

A using directive names a namespace and does not declare any names. Instead it will modify name lookup to find names that aren’t really declared where it thinks they are. For unqualified name lookup, it find names declared in the enclosing namespace that encloses both the using directive and the target namespace. All names that are declared in the target namespaces will be found:

Here, cout will be thought as being declared twice in the global namespace, and causes an ambiguity ( :: encloses both main and std ). In qualified namelookup, it will build the transitive closure of a namespace with all the namespaces named in using directives.

c is not only looked up in the global namespace, but also in the namespace foo and in the namespaces that foo has using directives for and so on. If however the global namespace would contain a direct declaration (including a using declaration), that declaration will hide the declarations found indirectly by using directives:

Using declarations can appear in many places, including inside class definitions. Its meaning is similar to its meaning otherwhere with an important restriction: It declares a name to be an alias to one or more declarations, but the declarations must be members of a base class. This is very useful for making names visible in a derived class that would otherwise be hidden by the same name declared there

Now you can call d.f() . If there were no using declaration, then name lookup would only find one declaration of f in derived and stop lookup, not delving into the base class scope:

It also allows to change the accessibility of base-class members, although you should use that sparingly 🙂

In practice, i found it useful for making virtual member function re-visible:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *