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


Пространства имен и директивы using

Подсказка

Вы новичок в разработке программного обеспечения? Сначала начните с учебников для начинающих. Они вводят пространства имен и using директивы, когда вы начинаете писать свои первые программы.

Есть опыт на другом языке? Пространства имен в C# работают похожим образом, как пакеты в Java или модули в Python. Перейдите к нужному синтаксису.

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

Вы уже использовали пространства имен в каждой программе C#, которую вы написали. Каждый тип .NET принадлежит пространству имен, и каждая using директива в верхней части файла ссылается на один. Например, Console и Math принадлежат к пространству имен System, поэтому их полные имена — это System.Console и System.Math. Типы коллекций, подобные List<T> и Dictionary<TKey, TValue>, принадлежащие System.Collections.Generic. using Одна директива для любого из этих пространств имен позволяет ссылаться на все его типы по простым именам. Вы пишете List<T> вместо того, чтобы System.Collections.Generic.List<T> везде, где вы его используете.

В этой статье содержатся дополнительные сведения о работе пространств имен и using директив, а также примеры шаблонов, которые вы уже обнаружили в библиотеках .NET.

Пространство имен содержит типы. Каждый тип .NET принадлежит пространству имен. Например, рассмотрим System.Threading.Tasks.Task: тип Task принадлежит пространству System.Threading.Tasks имен.

Рекомендуется группировать связанные или аналогичные типы в одном пространстве имен, и это то, что делает .NET с указанными типами. Пространство имен System.Collections.Generic содержит типы, связанные с коллекцией, а пространство имен System.IO содержит типы, связанные с работой с чтением и записью файлов, каталогов и данных. Пространство System имен содержит основные типы, такие как Math, DateTimeи Console.

В следующем примере показано, как пространства имен работают вместе с using директивами в типичном файле C#:

using System.Globalization;

namespace MyApp.Services;

class Greeter
{
    public string Greet(string name)
    {
        var culture = CultureInfo.CurrentCulture;
        return $"Hello, {name}! Culture: {culture.Name}";
    }
}

В предыдущем примере директива using означает, что вы можете использовать System.Globalization.CultureInfo по имени CultureInfo без необходимости указывать полное имя System.Globalization.CultureInfo. Директива namespace объявляет, что Greeter класс является частью MyApp.Services пространства имен. Полное имя MyApp.Services.Greeter.

Объявления пространства имен

Объявление пространства имен присваивает ваши типы к названной группе. Каждый тип, который вы записываете, должен принадлежать пространству имен. Имя пространства имен обычно отражает структуру папок проекта. Например, типы в папке Services/Payments часто принадлежат пространству имен MyApp.Services.Payments.

Пространства имен используют оператор . для выражения иерархии, например System.Collections.Generic. Имена пространств имен в C# должны быть допустимыми именами идентификаторов.

Пространства имен с областью действия файла

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

namespace MyApp.Models;

class Customer
{
    public required string Name { get; init; }
    public string? Email { get; init; }

    public override string ToString() => $"{Name} ({Email ?? "no email"})";
}

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

Подсказка

Используйте пространства имен, ограниченные файлом, в новом коде. Большинство шаблонов .NET и анализаторов кода рекомендуют этот стиль.

Блочные пространства имен

Используйте синтаксис блочной области видимости, если необходимо объявить несколько пространств имен в одном файле. Этот стиль добавляет дополнительный уровень отступа.

Это важно

Считается плохой практикой объявлять более одного пространства имен в одном файле. Более распространенный сценарий — использовать пространства имен с областью действия файла .

Следующий фрагмент кода является примером блочного пространства имен:

namespace MyApp.Models
{
    class Product
    {
        public required string Name { get; init; }
        public decimal Price { get; init; }

        public override string ToString() => $"{Name}: {Price:C}";
    }
}

Директивы using

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

static void ShowFullyQualified()
{
    // Without a using directive, use the fully qualified name:
    System.Console.WriteLine("Hello from fully qualified name!");
}

На верхней части файла присутствует директива using, которая импортирует пространство имен, позволяя использовать его типы по их простым именам:

static void ShowShortName()
{
    // With 'using System;' (or implicit usings enabled), use the short name:
    Console.WriteLine("Hello from short name!");
}

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

Глобальные директивы using

Если вы пишете одни и те же using директивы в каждом файле, директивы global using позволяют объявить их один раз для всего проекта. Поместите их в любой файл. Многие команды создают выделенный GlobalUsings.cs файл:

global using System.Text;
global using System.Text.Json;

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

Неявное использование

SDK для .NET автоматически создает глобальные директивы using для наиболее распространенных пространств имен в зависимости от типа вашего проекта. Включите неявное использование, установив <ImplicitUsings>enable</ImplicitUsings> в файле проекта. Например, проект консольного приложения автоматически импортирует System, System.Collections.Generic, System.IO, System.Linq, System.Threading и System.Threading.Tasks. Текущий пакет SDK включает ImplicitUsings при создании нового проекта с помощью dotnet new.

См. раздел «Неявные директивы using» для получения дополнительной информации.

Статические директивы using

Директива static using импортирует статические элементы типа, чтобы их можно было вызывать без префикса имени типа:

using static System.Math;

namespace MyApp.Utilities;

class CircleCalculator
{
    public static double CalculateArea(double radius) => PI * Pow(radius, 2);

    public static double CalculateCircumference(double radius) => 2 * PI * radius;
}

Статические использования хорошо работают для служебных классов, таких как Math и Console, которые вы часто вызываете.

Псевдонимы типа и пространства имен

Псевдоним using создает сокращенное имя для типа или пространства имен. Псевдонимы полезны для длинных общих типов, разрешения конфликтов именования и повышения удобочитаемости.

using CustomerList = System.Collections.Generic.List<MyApp.Models.Customer>;

namespace MyApp.Services;

class CustomerService
{
    public CustomerList GetTopCustomers()
    {
        CustomerList customers = [new() { Name = "Alice" }, new() { Name = "Bob" }];
        return customers;
    }
}

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

using Point = (double X, double Y);

namespace MyApp.Geometry;

class Shape
{
    public static double Distance(Point a, Point b)
    {
        var dx = a.X - b.X;
        var dy = a.Y - b.Y;
        return Math.Sqrt(dx * dx + dy * dy);
    }
}

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