Поделиться через


директиву using

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

using System.Text;

К директиве using можно применить два модификатора:

  • Модификатор global действует так же, как и добавление одной директивы using к каждому исходному файлу в проекте. Впервые этот модификатор появился в C# 10.
  • Модификатор static импортирует элементы static и вложенные типы из одного типа, а не из всех типов в пространстве имен.

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

Теперь можно также создать псевдоним для пространства имен или типа, используя директиву псевдонимов using.

using Project = PC.MyCompany.Project;

Модификатор global можно использовать в директиве using alias.

Примечание.

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

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

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

Другие using директивы могут отображаться:

  • В начале файла исходного кода перед объявлениями пространств имен и типов.
  • В любом заблокированном пространстве имен, но до любых пространств имен или типов, объявленных в этом пространстве имен.

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

Создайте директиву using, чтобы использовать типы в пространстве имен без необходимости указания этого пространства имен. Директива using не предоставляет доступ ни к одному из пространств имен, вложенных в указанное пространство имен. Пространства имен делятся на две категории: пользовательские и системные. Пользовательские пространства имен задаются в вашем коде. Список системных пространств имен см. в разделе Браузер API .NET.

global Модификатор

Добавление модификатора global к директиве using означает, что директива using должна применяться ко всем файлам в компиляции (обычно это проект). Директива global using впервые появилась в C# 10. Синтаксис:

global using <fully-qualified-namespace>;

Где полное пространство имен — полное имя пространства имен, типы которого можно ссылаться без указания пространства имен.

Директива global using может находиться в начале любого файла исходного кода. Все директивы global using в одном файле должны предшествовать:

  • Всем директивам using без модификатора global.
  • Всем объявлениям пространств имен и типов в файле.

Директивы можно добавить global using в любой исходный файл. Как правило, их следует хранить в одном расположении. Порядок директив global using не имеет значения ни в одном файле, ни в нескольких.

global Модификатор можно объединить с модификаторомstatic. global Модификатор можно применить к директиве псевдонима. В обоих случаях директива применяется ко всем файлам в текущей компиляции. Следующий пример включает использование всех методов, объявленных в System.Math во всех файлах проекта:

global using static System.Math;

Вы также можете включить пространства имен глобально, добавив элемент <Using> в файл проекта, например так: <Using Include="My.Awesome.Namespace" />. Дополнительные сведения см. в разделе, посвященном элементу <Using>.

Анализаторы диагностика, если повторять global директивы с помощью разных расположений. Эти же анализаторы также сообщают о добавлении using директивы для пространства имен или типа, на которые global уже ссылается директива using. Вы можете упростить управление global использованием, сохраняя их вместе в одном файле в проекте.

Внимание

В шаблонах C# для .NET 6 используются операторы верхнего уровня. Приложение может не соответствовать коду в этой статье, если вы уже обновили его до .NET 6. Дополнительные сведения см. в статье Новые шаблоны C# для создания инструкций верхнего уровня.

Пакет SDK для .NET 6 также добавляет набор неявных директив global using для проектов, использующих следующие пакеты SDK:

  • Microsoft.NET.Sdk
  • Microsoft.NET.Sdk.Web
  • Microsoft.NET.Sdk.Worker

Эти неявные директивы global using включают наиболее распространенные пространства имен для соответствующего типа проектов.

Дополнительные сведения см. в статье о неявных директивах using

static Модификатор

Директива using static указывает тип, доступ к статическим членам и вложенным типам которого можно получить, не указывая имя типа. Синтаксис:

using static <fully-qualified-type-name>;

<fully-qualified-type-name> — это имя типа, на статические члены и вложенные типы которого можно ссылаться, не указывая имя типа. Если полное доменное имя (полное имя пространства имен вместе с именем типа) не указано, C# создает ошибку компилятора CS0246: "Тип или пространство имен 'type/namespace' не найдены (отсутствует директива using или ссылка сборки)".

Директива using static применяется к каждому типу, у которого есть статические члены (или вложенные типы), даже если при этом у него также имеются члены экземпляров. При этом для вызова членов экземпляров можно использовать только экземпляр типа.

Вы можете обращаться к статическим членам типа без необходимости квалификации доступа с помощью имени типа:

using static System.Console;
using static System.Math;
class Program
{
    static void Main()
    {
        WriteLine(Sqrt(3*3 + 4*4));
    }
}

Обычно при вызове статического члена необходимо указать имя типа и имя нужного члена. Повторный ввод одного и того же имени типа для вызова относящихся к нему элементов может сделать код слишком длинным и сложным. Например, следующее определение класса Circle ссылается на многие члены класса Math.

using System;

public class Circle
{
   public Circle(double radius)
   {
      Radius = radius;
   }

   public double Radius { get; set; }

   public double Diameter
   {
      get { return 2 * Radius; }
   }

   public double Circumference
   {
      get { return 2 * Radius * Math.PI; }
   }

   public double Area
   {
      get { return Math.PI * Math.Pow(Radius, 2); }
   }
}

Поскольку явно ссылаться на класс Math при каждой ссылке на член не требуется, директива using static создает более понятный код:

using System;
using static System.Math;

public class Circle
{
   public Circle(double radius)
   {
      Radius = radius;
   }

   public double Radius { get; set; }

   public double Diameter
   {
      get { return 2 * Radius; }
   }

   public double Circumference
   {
      get { return 2 * Radius * PI; }
   }

   public double Area
   {
      get { return PI * Pow(Radius, 2); }
   }
}

using static импортирует только доступные статические члены и вложенные типы, объявленные в указанном типе. Унаследованные члены не импортируются. Можно импортировать из любого именованного типа с помощью директивы using static, включая модули Visual Basic. Если функции F# верхнего уровня отображаются в метаданных как статические члены именованного типа, имя которого является допустимым идентификатором C#, то эти функции F# можно импортировать.

using static делает методы расширения, объявленные в указанном типе, доступными для поиска метода расширения. Тем не менее имена методов расширения не импортируются в область для неквалифицированной ссылки в коде.

Методы с тем же именем, импортированные из различных типов разными директивами using static в том же блоке компиляции или пространстве имен, формируют группу методов. Разрешение перегрузки в этих группах методов соответствует обычным правилам языка C#.

В следующем примере директива using static используется для того, чтобы доступ к статическим членам классов Console, Math и String можно было получать, не указывая имя типа.

using System;
using static System.Console;
using static System.Math;
using static System.String;

class Program
{
   static void Main()
   {
      Write("Enter a circle's radius: ");
      var input = ReadLine();
      if (!IsNullOrEmpty(input) && double.TryParse(input, out var radius)) {
         var c = new Circle(radius);

         string s = "\nInformation about the circle:\n";
         s = s + Format("   Radius: {0:N2}\n", c.Radius);
         s = s + Format("   Diameter: {0:N2}\n", c.Diameter);
         s = s + Format("   Circumference: {0:N2}\n", c.Circumference);
         s = s + Format("   Area: {0:N2}\n", c.Area);
         WriteLine(s);
      }
      else {
         WriteLine("Invalid input...");
      }
   }
}

public class Circle
{
   public Circle(double radius)
   {
      Radius = radius;
   }

   public double Radius { get; set; }

   public double Diameter
   {
      get { return 2 * Radius; }
   }

   public double Circumference
   {
      get { return 2 * Radius * PI; }
   }

   public double Area
   {
      get { return PI * Pow(Radius, 2); }
   }
}
// The example displays the following output:
//       Enter a circle's radius: 12.45
//
//       Information about the circle:
//          Radius: 12.45
//          Diameter: 24.90
//          Circumference: 78.23
//          Area: 486.95

В примере using static директива также может применяться к типу Double . Добавление этой директивы позволит вызывать метод TryParse(String, Double), не указывая имя типа. При этом, когда TryParse используется без указания имени типа, код становится менее понятным, поскольку появляется необходимость проверять директивы using static и определять, какой метод числового типа TryParse вызывается.

using static также применяется к типам enum. Если вы добавите using static с перечислением, в типе уже не обязательно использовать элементы перечисления.

using static Color;

enum Color
{
    Red,
    Green,
    Blue
}

class Program
{
    public static void Main()
    {
        Color color = Green;
    }
}

using Псевдоним

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

using s = System.Text;
using s.RegularExpressions; // Generates a compiler error.

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

namespace PC
{
    // Define an alias for the nested namespace.
    using Project = PC.MyCompany.Project;
    class A
    {
        void M()
        {
            // Use the alias
            var mc = new Project.MyClass();
        }
    }
    namespace MyCompany
    {
        namespace Project
        {
            public class MyClass { }
        }
    }
}

Псевдоним using не может иметь открытый универсальный тип с правой стороны. Например, нельзя создать псевдоним using для List<T>, но можно создать его для List<int>.

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

using System;

// Using alias directive for a class.
using AliasToMyClass = NameSpace1.MyClass;

// Using alias directive for a generic class.
using UsingAlias = NameSpace2.MyClass<int>;

namespace NameSpace1
{
    public class MyClass
    {
        public override string ToString()
        {
            return "You are in NameSpace1.MyClass.";
        }
    }
}

namespace NameSpace2
{
    class MyClass<T>
    {
        public override string ToString()
        {
            return "You are in NameSpace2.MyClass.";
        }
    }
}

namespace NameSpace3
{
    class MainClass
    {
        static void Main()
        {
            var instance1 = new AliasToMyClass();
            Console.WriteLine(instance1);

            var instance2 = new UsingAlias();
            Console.WriteLine(instance2);
        }
    }
}
// Output:
//    You are in NameSpace1.MyClass.
//    You are in NameSpace2.MyClass.

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

Квалифицированный член псевдонима

Квалификатор :: пространства имен предоставляет явный доступ к глобальному пространству имен или другим псевдонимам, потенциально скрытым другими сущностями.

Гарантирует global:: , что поиск пространства имен для пространства имен после маркера :: соответствует глобальному пространству имен. В противном случае маркер должен разрешаться в псевдоним, а маркер, следующий за :: типом в этом псевдониме пространства имен. В следующем примере показаны обе формы:

using S = System.Net.Sockets;

class A
{
    public static int x;
}

class C
{
    public void F(int A, object S)
    {
        // Use global::A.x instead of A.x
        global::A.x += A;

        // Using ::, S must resolve to a namespace alias:
        S::Socket s = S as S::Socket;

        // In this form, if S were a class, it would be a compile-time error:
        S.Socket s1 = S as S.Socket;
    }
}

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

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

Дополнительные сведения об использовании модификатора global using см. в спецификации функции global using — C# 10.

См. также