Каково предназначение инструкции using в начале кодового файла

Search code, repositories, users, issues, pull requests…

Provide feedback

Saved searches

Use saved searches to filter your results more quickly

Sign up

В данной статье будет рассказано о том, что собой представляет пространство имен в C#. Предстоит познакомиться с директивами типа using, а также рассмотреть наглядные примеры использования упомянутых компонентов.

Директива – это…

Директива – это указание. Определение соответствующего понятия в программировании напоминает термин «команда». Он используется для описания некоторых конструкций ЯП. Указывает, как компилятор или любой иной транслятор должен обрабатывать вводимые данные.

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

Иногда подобные компоненты отвечают за определение глобального поведения, а в некоторых ситуациях действуют локально. В программах на C не являются обязательными. Они могут быть проигнорированы компилятором. Чаще всего носят предписывающий характер. В самом языке директивы (using и не только) не отвечают за выполнение тех или иных действий ЯП – они лишь корректируют поведение компиляторов.

Пространства имен – что это

Пространства имен (namespace) – это то, что позволяет выделить определенные части приложений в логические блоки. Поддерживается работа с:

  • классами;
  • интерфейсами;
  • прочими элементами программного кода.

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

При помощи упомянутого элемента можно сохранить один набор имен (пример – имена классов) отличным от других наборов имен. Преимуществом такого подхода является то, что имена классов, объявленные в пределах одного пространства, не конфликтуют с аналогичными, но в других пространствах.

Членами могут выступать:

  • пространства имен;
  • структуры;
  • делегаты.

Пространства имен можно охарактеризовать как группу классов, обладающих общими признаками.

Свойства

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

  • организация масштабных проектов по созданию программных кодов;
  • разделение происходит при помощи оператора «.» (точки);
  • global – корневая область имен.

Using – директива, которая позволяет исключить требование на указание названия области имен для каждого класса. Данный компонент избавляет от полной классификации «названий». Далее соответствующий элемент будет рассмотрен более подробно.

Using – описание

Директивы using – это то, что производит импорт именных областей, избавляя разработчика от полной классификации имен стереотипов. Дает возможность задействовать определенные типы без указания полной области «названий» соответствующего типа. В базовой форме used используется импорт всех типов именных пространств.

Using directive поддерживает применение двух модификаторов:

  1. Модификатор global. Он будет работать точно так, как и добавление одной директивы use к каждому исходному документу в пределах проекта. Первое появление состоялось в C Sharp 10 версии.
  2. Модификатор static. Он производит импорт элементов static, а также вложенных типов из одного типа, а не из всех в пределах области «названий».

Оба модификатора можно использовать вместе для импорта статистических членов из того или иного типа во всех исходных проектных файлах.

Сейчас C# поддерживает создание псевдонимов для namespace. Для этого используется директива псевдонимов using:

using Project = PC.MyCompany.Project;

Модификатор global используется в using alias. Без него область будет ограничиваться файлом, в пределах которого находится директива.

Особенности

Директива using в C# имеет ряд особенностей. Она отображается в нескольких местах – все зависит от ситуации:

  1. Начало документа в исходном коде. Перед тем, как объявлять именные «области», а также типы.
  2. В любом namespace, но до пространственных имен, объявленных в первой «области». Здесь обязательно, чтобы не использовался модификатор global. Если он присутствует, директива using располагается перед всеми объявлениями.

Если не соблюдать данные принципы, при попытке обработки кода появится ошибка компиляции CS1529.

Директива using создается для того, чтобы использовать типы в пространстве имен без необходимости указания его самого. Если использовать using System, больше не придется вводить полный путь. Методы в приложении получится вызывать быстрее и короче.

Using – это ключевое слово, которое в C# имеет широкое применение. Оно используется для создания операторов using. Данные элементы используются для грамотной обработки объектов IDisposable – шрифтов и файлов.

Псевдонимы

Using alias – это директива, позволяющая создавать псевдонимы для namespaces. У нее не может быть открытого универсального типа в правой части. Создать его для List<T> не получится, но можно для List<int>.

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

Для подключения using alias потребуется:

  1. Добавить в References желаемые сборки.
  2. Открыть соответствующую папку и кликнуть по сборке правой кнопкой мышки.
  3. Выбрать раздел Properties.
  4. Нажать на свойство Aliases.

После этого остается заменить значение global на свое собственное название.

Наглядный пример

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

Здесь в операторе using в круглых скобках написано выражение, обработка которого приводит к получению специального объекта. Он будет реализовывать интерфейс System IDisposable. Если объект не реализует интерфейс, на экране появится сообщение об ошибке.

В приведенном фрагменте объект определяется за пределами оператора using. Соответствующий код может быть записан так:

После обработки блока using в C происходит автоматический вызов метода Dispose(). Он осуществляется для переданного ранее объекта и располагается в интерфейсе System.IDisposable.

При использовании потоков необходимо запомнить – при завершении оперирования ими требуется завершать соответствующие процессы. Аналогичные принципы применяются к базам данных, сокетам, иным источникам. Метод Dispose() будет каждый раз завершать работу с потоком и высвобождать ресурсы.

А вот более простой фрагмент программы:

Здесь:

  1. Using namespace std указывает компилятору на импорт всех имен из пространства std в текущую область видимости. В приведенном примере таковым является main().
  2. После использования неполного идентификатора count происходит преобразование в std::count.

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

Как лучше освоить

C# – язык, который пользуется спросом у разработчиков. Для того, чтобы хорошенько изучить его директивы, а также пространства имен и иные элементы, можно заняться самообразованием. Это не лучшее решение – обучение может затянуться, а доказать полученные навыки и знания документально окажется невозможно. Именно поэтому рекомендуется отдать предпочтение дистанционным онлайн курсам.

Они рассчитаны на широкую публику и прекрасно совмещаются со всеми делами – уроки можно просматривать в любое время. Курсы рассчитаны на срок до 12 месяцев. Пользователи получают шанс выбрать одновременно одно или несколько инновационных IT-направлений для изучения. Процесс сопровождается домашними заданиями и богатой практикой. В конце обучения выдается электронный сертификат, подтверждающий приобретенный спектр навыков и знаний.

Хотите освоить современную IT-специальность? Огромный выбор курсов по востребованным IT-направлениям есть в Otus!

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

int main() {
  using std::swap;
  // ...
}

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:

int cout;
int main() {
  using namespace std;
  // cout << 1; ambiguous!
}

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.

using namespace foo;

int main() {
  ::c++; 
}

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 namespace foo;
int c;

int main() {
  ::c++; // not ambiguous!
}

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

struct base {
  void f();
};

struct derived : base {
  using base::f; // name "f" declared in derived
  void f(int); // overloads the using declaration
};

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:

derived d;
d.f(); // invalid without the using declaration
d.f(0); // valid with or without the using declaration

// explicitly starting lookup in base: valid with or without the using declaration
d.base::f();

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:

struct base {
  virtual void f();
  virtual void f(int);
};

struct derived : base {
  // using base::f; would solve it
  virtual void f() { ... }
};

Oops — now d.f(0); is invalid because name lookup only finds the zero parameter f! The using directive would solve it. Notice that if you alias a function declaration that has the same parameter types and constness as an explicit declaration (like f() in this case), then the explicit declaration will still hide the one that the using declaration is an alias for — so both f() functions won’t conflict in this case.

An alternative to solve this is using the non-virtual interface idiom

struct base {
  void f() { do_f(); }
  void f(int) { do_f(0); }

private:
  virtual void do_f();
  virtual void do_f(int);
};

struct derived : base {
private:
  virtual void do_f() { ... }
};

struct derived1 : derived {
private:
  virtual void do_f(int) { ... }
};

Now, both d.f(0) and d.f() are valid no matter on what object you call it.

Последнее обновление: 18.02.2022

В прошлой теме, где рассматривалась реализация метода Dispose, говорилось, что для его вызова можно использовать следующую конструкцию try..catch:

Test();

void Test()
{
    Person? tom = null;
    try
    {
        tom = new Person("Tom");
    }
    finally
    {
        tom?.Dispose();
    }
}
public class Person : IDisposable
{
    public string Name { get;}
    public Person(string name) => Name = name;

    public void Dispose() => Console.WriteLine($"{Name} has been disposed");
}

Однако синтаксис C# также предлагает синонимичную конструкцию для автоматического вызова метод Dispose — конструкцию using:

using (Person tom = new Person("Tom"))
{
}

Конструкция using оформляет блок кода и создает объект некоторого типа, который реализует интерфейс IDisposable, в частности, его метод Dispose. При завершении блока
кода у объекта вызывается метод Dispose.

Важно, что данная конструкция применяется только для типов, которые реализуют интерфейс IDisposable.

Ее использование:

Test();

void Test()
{
    using (Person tom = new Person("Tom"))
    {
        // переменная tom доступна только в блоке using
        // некоторые действия с объектом Person
        Console.WriteLine($"Name: {tom.Name}");
    }
    Console.WriteLine("Конец метода Test");
}
public class Person : IDisposable
{
    public string Name { get;}
    public Person(string name) => Name = name;

    public void Dispose() => Console.WriteLine($"{Name} has been disposed");
}

Консольный вывод:

Name: Tom
Tom has been disposed
Конец метода Test

Здесь мы видим, что по завершении блока using у объекта Person вызывается метод Dispose. Вне блока кода using объект tom не существует.

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

Test();

void Test()
{
    using Person tom = new Person("Tom");
    
    // переменная tom доступна только в блоке using
    // некоторые действия с объектом Person
    Console.WriteLine($"Name: {tom.Name}");
    Console.WriteLine("Конец метода Test");
}
public class Person : IDisposable
{
    public string Name { get;}
    public Person(string name) => Name = name;

    public void Dispose() => Console.WriteLine($"{Name} has been disposed");
}

В данном случае using сообщает компилятору, что объявляемая переменная должна быть удалена в конце области видимости — то есть в конце метода Test.
Соответственно мы получим следующий консольный вывод:

Name: Tom
Конец метода Test
Tom has been disposed

Освобождение множества ресурсов

Для освобождения множества ресурсов мы можем применять вложенные конструкции using. Например:

void Test()
{
	using (Person tom = new Person("Tom"))
	{
		using (Person bob = new Person("Bob"))
		{
			Console.WriteLine($"Person1: {tom.Name}    Person2: {bob.Name}");
		}// вызов метода Dispose для объекта bob
	} // вызов метода Dispose для объекта tom
	Console.WriteLine("Конец метода Test");
}

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

Мы можем сократить это определение:

void Test()
{
	using (Person tom = new Person("Tom"))
	using(Person bob = new Person("Bob"))
	{
		Console.WriteLine($"Person1: {tom.Name}    Person2: {bob.Name}");
	} // вызов метода Dispose для объектов bob и tom
	Console.WriteLine("Конец метода Test");
}

И, как уже было выше сказано, в C# мы можем задать в качестве области действия для объектов, создаваемых в конструкции using, весь метод:

private static void Test()
{
	using Person tom = new Person { Name = "Tom" };
	using Person bob = new Person { Name = "Bob" };
	
	Console.WriteLine($"Person1: {tom.Name}    Person2: {bob.Name}");
	
	Console.WriteLine("Конец метода Test");
} // вызов метода Dispose для объектов bob и tom

I saw this C# using statement in a code example:

using StringFormat=System.Drawing.StringFormat;

What’s that all about?

Luke Girvin's user avatar

Luke Girvin

13.2k9 gold badges63 silver badges84 bronze badges

asked Jun 23, 2009 at 20:44

Ronnie Overby's user avatar

Ronnie OverbyRonnie Overby

45.1k73 gold badges267 silver badges346 bronze badges

2

That’s aliasing a typename to a shorter name. The same syntax can also be used for aliasing namespaces. See using directive.

(Updated in response to Richard)

answered Jun 23, 2009 at 20:46

Sean's user avatar

3

It’s an alias, from now on, the user can use StringFormat to refer to System.Drawing.StringFormat. It’s useful if you don’t want to use the whole namespace (in case of name clash issues for example).

source: using Directive article from MSDN

Scott Ivey's user avatar

Scott Ivey

40.7k21 gold badges80 silver badges118 bronze badges

answered Jun 23, 2009 at 20:46

mbillard's user avatar

mbillardmbillard

38.3k18 gold badges73 silver badges98 bronze badges

1

Perhaps a different, unrelated StringFormat is declared in another namespace like Acme.Stuff. If that were the case, this would cause confusion:

using System.Drawing; // Contains StringFormat type.
using Acme.Stuff;  // Contains another StringFormat type.

private void Foo()
{
    StringFormat myFormat = new StringFormat(); // which one to use?
}

Aliasing is with using on the StringFormat=System.Drawing.StringFormat clears up some of the confusion.

Richard's user avatar

Richard

107k21 gold badges203 silver badges265 bronze badges

answered Jun 23, 2009 at 20:48

Bullines's user avatar

BullinesBullines

5,6166 gold badges53 silver badges93 bronze badges

It means you’re using StringFormat as an alias for System.Drawing.StringFormat;

answered Jun 23, 2009 at 20:46

Fiur's user avatar

FiurFiur

6321 gold badge6 silver badges20 bronze badges

This will define an alias to System.Drawing.StringFormat.

That’s the same thing like this example:

using SQL = System.Data.SqlServer;

SQL.SqlConnection sql = new SQL.SqlConnection();

answered Jun 23, 2009 at 20:47

Zanoni's user avatar

ZanoniZanoni

29.9k13 gold badges53 silver badges73 bronze badges

It’s a alias for the namespace

answered Jun 23, 2009 at 20:47

Fossmo's user avatar

FossmoFossmo

2,8624 gold badges25 silver badges47 bronze badges

The using keyword is used for importing namespaces or aliasing classes or for managing scope on disposable objects. Here we are talking about the namespace usage.

using StringFormat=System.Drawing.StringFormat;

The way using was used here is a little unusual in C# but more common in Java import statements. What it does is provide a StringFormat alias without importing the entire System.Drawing namespace. Some people with a Java background like to proactvely import only the classes being used rather than whole anmespaces (aka Java packages). Arguably you proactively avoid potential name conflicts if you import only specific class names but it isn’t very common in C# and Visual Studio doesn’t encourage it the way, say, Netbeans does for Java.

The more common usuage of aliasing is to resolve class names to a shortened alias when there is a naming conflict.

using System.Drawing;
using AwesomeCompany.ReallyAwesomeStuff.AwesomeLibrary.Drawing;
/* AwesomeCompany.ReallyAwesomeStuff.AwesomeLibrary.Drawing has a StringFormat class */
using AwesomeStringFormat = AwesomeCompany.ReallyAwesomeStuff.AwesomeLibrary.Drawing.Stringformat;
using StringFormat = System.Drawing.StringFormat;

public class AwesomeForm() : Form
{
    private AwesomeForm()
    {
        AwesomeStringFormat stringFormat = new AwesomeStringFormat();
        stringFormat.Color = Color.Red;
        /* etc */
    }
}

Richard's user avatar

Richard

107k21 gold badges203 silver badges265 bronze badges

answered Jun 23, 2009 at 21:31

Brian Reiter's user avatar

Brian ReiterBrian Reiter

1,3391 gold badge10 silver badges16 bronze badges

Понравилась статья? Поделить с друзьями:
  • Каково назначение инструкции по охране труда для кого их составляют
  • Каково место должностной инструкции в системе источников трудового права
  • Какова структура текста должностной инструкции
  • Какова структура инструкции по безопасности труда
  • Какова структура и содержание инструкций по охране труда кратко