Obory názvů a direktivy 'using'

Návod

Začínáte s vývojem softwaru? Začněte nejprve kurzy Začínáme . Když píšete své první programy, zavádějí obory názvů a using direktivy.

Máte zkušenosti v jiném jazyce? Jmenné prostory v jazyce C# fungují podobně jako balíčky v Javě nebo moduly v Pythonu. Přeskočte na syntaxi, kterou potřebujete.

Deklarace oboru názvů a using direktivy jsou související jazykové funkce. Deklarace oboru názvů umístí typy do uspořádané struktury. Obor názvů seskupuje související typy a zabraňuje kolizím názvů. Direktiva using umožňuje vašemu programu používat tyto typy podle jejich jednoduchých názvů. Při každém použití nemusíte uvádět úplnou cestu oboru názvů.

Obory názvů jste už použili v každém programu jazyka C#, který jste napsali. Každý typ .NET patří do oboru názvů a každá using direktiva v horní části souboru odkazuje na jeden. Například Console a Math patří do System oboru názvů, takže jejich plně kvalifikované názvy jsou System.Console a System.Math. Typy kolekcí jako List<T> a Dictionary<TKey, TValue> patří do System.Collections.Generic. Jedna using direktiva pro některý z těchto oborů názvů umožňuje odkazovat na všechny jeho typy pomocí jejich jednoduchých názvů. Píšete List<T> místo System.Collections.Generic.List<T> všude, kde ho používáte.

Tento článek obsahuje další informace o tom, jak fungují obory názvů a using direktivy, a ukazuje příklady vzorů, se kterými jste se už v knihovnách .NET setkali.

Jmenný prostor obsahuje typy. Každý typ .NET patří do oboru názvů. Představte si System.Threading.Tasks.Tasknapříklad: typ Task patří do System.Threading.Tasks oboru názvů.

Je vhodné seskupit související nebo podobné typy ve stejném oboru názvů a to dělá .NET s typy, které poskytuje. Obor System.Collections.Generic názvů obsahuje typy související s kolekcí a System.IO obor názvů obsahuje typy související se čtením a zápisem souborů, adresářů a dat. Obor System názvů obsahuje základní typy, jako je Math, DateTimea Console.

Následující příklad ukazuje, jak obory názvů spolupracují s using direktivami v typickém souboru jazyka C#:

using System;
using System.Globalization;

namespace MyApp.Services;

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

V předchozím příkladu direktiva using znamená, že můžete použít System.Globalization.CultureInfo pod názvem CultureInfo bez nutnosti zadání plného názvu System.Globalization.CultureInfo. Direktiva namespace deklaruje, že Greeter třída je součástí MyApp.Services oboru názvů. Jeho plně kvalifikovaný název je MyApp.Services.Greeter.

Deklarace jmenného prostoru

Deklarace oboru názvů přiřadí vaše typy pojmenované skupině. Každý typ, který napíšete, by měl patřit do oboru názvů. Název oboru názvů obvykle zrcadlí strukturu složek vašeho projektu. Například typy ve Services/Payments složce často patří do MyApp.Services.Payments oboru názvů.

Jmenné prostory používají . operátor k vyjádření hierarchie, například System.Collections.Generic. Názvy oborů názvů musí být platné názvy identifikátorů jazyka C#.

Prostor jmen pro soubory

Syntaxi s oborem souborů použijte, pokud všechny typy v souboru patří do stejného oboru názvů. Za deklaraci oboru názvů přidejte středník a vztahuje se na celý soubor. Nepotřebujete další složené závorky ani odsazení:

namespace MyApp.Models;

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

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

Jmenné prostory omezené na soubory snižují vnoření a usnadňují čtení souborů. Můžete mít pouze jednu deklaraci oboru názvů na soubor.

Návod

Používejte obory názvů definované souborem v novém kódu. Tento styl doporučuje většina šablon .NET a analyzátorů kódu.

Jmenné prostory s rozsahem na úrovni bloku

Syntaxi s oborem bloku použijte, pokud potřebujete deklarovat více než jeden obor názvů ve stejném souboru. Tento styl přidá další úroveň odsazení.

Důležité

Je vzácné deklarovat více než jeden obor názvů ve stejném souboru. Nejběžnějším scénářem je použití oborů názvů na úrovni souboru.

Následující úsek kódu je příkladem oboru názvů omezeného na blok:

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

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

Použití direktiv

Bez direktivy using musíte na každý typ odkazovat jeho plně kvalifikovaným názvem, tedy úplnou cestou k oboru názvů a názvem typu. Tento styl je podrobný, opakující se a obtížně čitelný, zejména pokud soubor používá mnoho typů ze stejného oboru názvů:

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

Direktiva using v horní části souboru importuje obor názvů, takže jeho typy můžete použít podle jejich jednoduchých názvů. Následující úryvek kódu ukazuje použití kratšího zápisu typů po tomto příkazu import, díky němuž jsou odkazy v celém souboru kratší a lépe čitelné:

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

Další informace najdete v direktivěusing.

Globální direktivy using

Direktiva using se vztahuje pouze na soubor, ve který se zobrazuje. Místo opakování stejných using direktiv v každém souboru použijte globální direktivy using , které umožňují deklarovat je jednou pro celý projekt. Umístěte je do libovolného souboru. Mnoho týmů vytvoří vyhrazený GlobalUsings.cs soubor:

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

Po deklarování globálního usingu může každý soubor v projektu odkazovat na typy z daného oboru názvů pomocí jejich jednoduchých názvů bez další direktivy using. Globální direktivy using odstraňují opakování napříč soubory, zmenšují blok using v horní části každého souboru a centralizují zásady pro obory názvů v projektu.

Implicitní použití

Pro nejběžnější obory názvů nemusíte psát vůbec žádné direktivy using. Sada SDK .NET automaticky generuje globální direktivy using na základě typu projektu. Povolte implicitní použití nastavením <ImplicitUsings>enable</ImplicitUsings> v souboru projektu. Například projekt konzolové aplikace automaticky importuje System, System.Collections.Generic, System.IO, System.Linq, System.Threading a System.Threading.Tasks. Nové projekty, které vytvoříte pomocí dotnet new, mají ImplicitUsings ve výchozím nastavení povolené. Nové soubory jsou od začátku přehledné, bez nadbytečných direktiv using pro běžné typy, jako jsou Console, List<T> nebo Task.

Pro více informací viz Implicitní použití direktiv.

Note

Další ukázky kódu v tomto článku a většina ukázek v dokumentaci .NET předpokládá, že jsou povolená implicitní použití (nebo ekvivalentní globální použití pro typ projektu). Proto v horní části každého úryvku kódu nevidíte using System; a podobné direktivy, i když kód používá typy jako Console nebo List<T> pod jejich jednoduchými názvy.

Statické direktivy použití

Direktiva static using importuje statické členy typu, abyste je mohli volat bez předpony názvu typu:

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;
}

Statické použití funguje dobře pro třídy nástrojů, jako je Math a Console které často voláte.

Aliasy typů a jmenných prostorů

Alias using vytvoří zkratkový název pro typ nebo obor názvů. Aliasy jsou užitečné pro dlouhé obecné typy, řešení konfliktů názvů a zlepšení čitelnosti:

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;
    }
}

Od verze C# 12 můžete aliasovat libovolný typ, včetně n-tic a typů ukazatelů.

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);
    }
}

V pokročilejších scénářích, kdy dvě sestavení definují stejný plně kvalifikovaný název typu, použijte externí alias k odstranění nejednoznačnosti mezi nimi.