Dela via


Direktivet using

Med using direktivet kan du använda typer som definierats i ett namnområde utan att ange det fullständigt kvalificerade namnområdet för den typen. I sin grundläggande form using importerar direktivet alla typer från ett enda namnområde, enligt följande exempel:

using System.Text;

Du kan tillämpa två modifierare på ett using direktiv:

  • Modifieraren global har samma effekt som att lägga till samma using direktiv i varje källfil i projektet. Den här modifieraren introducerades i C# 10.
  • Modifieraren static importerar static medlemmar och kapslade typer från en enda typ i stället för att importera alla typer i ett namnområde.

Du kan kombinera båda modifierarna för att importera statiska medlemmar från en typ till alla källfiler i projektet.

Du kan också skapa ett alias för ett namnområde eller en typ med ett aliasdirektiv.

using Project = PC.MyCompany.Project;

Du kan använda modifieraren i global ett aliasdirektiv.

Kommentar

Nyckelordet using används också för att skapa using instruktioner som hjälper till att säkerställa att IDisposable objekt som filer och teckensnitt hanteras korrekt. Mer information om -instruktionen finns i using instruktionenusing.

Omfånget för ett using direktiv utan global modifieraren är den fil där det visas.

Direktivet global using måste visas före alla namnrymds- och typdeklarationer. Alla globala användningsdirektiv måste visas i en källfil före alla icke-globala using direktiv.

Andra using direktiv kan visas:

  • I början av en källkodsfil, innan någon namnrymd eller typdeklarationer.
  • I alla blockerade namnområden, men före namnområden eller typer som deklarerats i namnområdet.

Annars genereras ett kompilatorfel.

Skapa ett using direktiv för att använda typerna i ett namnområde utan att behöva ange namnområdet. Ett using direktiv ger dig inte åtkomst till några namnområden som är kapslade i det namnområde som du anger. Namnområden finns i två kategorier: användardefinierade och systemdefinierade. Användardefinierade namnområden är namnområden som definierats i koden. En lista över systemdefinierade namnområden finns i .NET API Browser.

Modifieraren global

Att lägga till modifieraren i global ett using direktiv innebär att användning tillämpas på alla filer i kompilering (vanligtvis ett projekt). Direktivet global using lades till i C# 10. Syntaxen är:

global using <fully-qualified-namespace>;

Där fullständigt kvalificerat namnområde är det fullständigt kvalificerade namnet på namnområdet vars typer kan refereras till utan att ange namnområdet.

Ett globalt användningsdirektiv kan visas i början av alla källkodsfiler. Alla global using direktiv i en enda fil måste visas innan:

  • Alla using direktiv utan global modifieraren.
  • Alla namnrymds- och typdeklarationer i filen.

Du kan lägga till global using direktiv i valfri källfil. Vanligtvis vill du behålla dem på en enda plats. Direktivordningen global using spelar ingen roll, varken i en enda fil eller mellan filer.

Modifieraren global kan kombineras med static modifieraren. Modifieraren global kan tillämpas på ett aliasdirektiv. I båda fallen är direktivets omfång alla filer i den aktuella kompileringen. I följande exempel kan du använda alla metoder som deklareras i System.Math alla filer i projektet:

global using static System.Math;

Du kan också inkludera ett namnområde globalt genom att lägga till ett <Using> objekt i projektfilen, till exempel <Using Include="My.Awesome.Namespace" />. Mer information finns i <Using> artikeln.

Analysverktyg utfärdar diagnostik om du duplicerar global med hjälp av direktiv på olika platser. Samma analysverktyg informerar dig också om du lägger till ett using direktiv för ett namnområde eller en typ som ett global användningsdirektiv redan refererar till. Det kan vara enklare att hantera dina global användningar genom att hålla ihop dem i en fil i projektet.

Viktigt!

C#-mallarna för .NET 6 använder toppnivåinstruktioner. Programmet kanske inte matchar koden i den här artikeln om du redan har uppgraderat till .NET 6. Mer information finns i artikeln om nya C#-mallar som genererar instruktioner på toppnivå

.NET 6 SDK lägger också till en uppsättning implicita global using direktiv för projekt som använder följande SDK:er:

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

Dessa implicita global using direktiv innehåller de vanligaste namnrymderna för projekttypen.

Mer information finns i artikeln om implicit användning av direktiv

Modifieraren static

Direktivet using static namnger en typ vars statiska medlemmar och kapslade typer du kan komma åt utan att ange ett typnamn. Syntaxen är:

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

<fully-qualified-type-name> är namnet på den typ vars statiska medlemmar och kapslade typer kan refereras utan att ange ett typnamn. Om du inte anger ett fullständigt kvalificerat typnamn (det fullständiga namnområdesnamnet tillsammans med typnamnet) genererar C# kompilatorfelet CS0246: "Det gick inte att hitta typ- eller namnområdesnamnet "type/namespace" (saknar du ett användningsdirektiv eller en sammansättningsreferens?)".

Direktivet using static gäller för alla typer som har statiska medlemmar (eller kapslade typer), även om det också har instansmedlemmar. Instansmedlemmar kan dock bara anropas via typinstansen.

Du kan komma åt statiska medlemmar av en typ utan att behöva kvalificera åtkomsten med typnamnet:

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

Normalt anger du typnamnet tillsammans med medlemsnamnet när du anropar en statisk medlem. Om du upprepade gånger anger samma typnamn för att anropa medlemmar av typen kan det resultera i utförlig, obskyr kod. Följande definition av en Circle klass refererar till exempel till många medlemmar i Math klassen.

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

Genom att eliminera behovet av att uttryckligen Math referera till klassen varje gång en medlem refereras skapar using static direktivet renare kod:

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 importerar endast tillgängliga statiska medlemmar och kapslade typer som deklarerats i den angivna typen. Ärvda medlemmar importeras inte. Du kan importera från valfri namngiven typ med ett using static direktiv, inklusive Visual Basic-moduler. Om F#-toppnivåfunktioner visas i metadata som statiska medlemmar av en namngiven typ vars namn är en giltig C#-identifierare kan F#-funktionerna importeras.

using static gör tilläggsmetoder som deklarerats i den angivna typen tillgängliga för tilläggsmetodsökning. Namnen på tilläggsmetoderna importeras dock inte till omfånget för okvalificerad referens i kod.

Metoder med samma namn som importerats från olika typer av olika using static direktiv i samma kompileringsenhet eller namnområde utgör en metodgrupp. Överbelastningsmatchning i dessa metodgrupper följer normala C#-regler.

I följande exempel används using static direktivet för att göra statiska medlemmar i klasserna Console, Mathoch och String tillgängliga utan att behöva ange deras typnamn.

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

I exemplet using static skulle direktivet också kunna tillämpas på Double typen. Om du lägger till det direktivet kan du anropa TryParse(String, Double) metoden utan att ange ett typnamn. Om du använder TryParse utan ett typnamn skapas dock mindre läsbar kod, eftersom det blir nödvändigt att kontrollera direktiven using static för att avgöra vilken numerisk typs metod som anropas TryParse .

using static gäller även för enum typer. Genom att lägga till using static med uppräkningen krävs inte längre typen för att använda uppräkningsmedlemmarna.

using static Color;

enum Color
{
    Red,
    Green,
    Blue
}

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

Aliaset using

Skapa ett using aliasdirektiv för att göra det enklare att kvalificera en identifierare till ett namnområde eller en typ. I alla using direktiv måste det fullständigt kvalificerade namnområdet eller typen användas oavsett vilka using direktiv som föregår det. Inget using alias kan användas i deklarationen av ett using direktiv. Följande exempel genererar till exempel ett kompilatorfel:

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

I följande exempel visas hur du definierar och använder ett using alias för ett namnområde:

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

Ett användningsaliasdirektiv kan inte ha en öppen allmän typ till höger. Du kan till exempel inte skapa ett med alias för en List<T>, men du kan skapa ett för en List<int>.

I följande exempel visas hur du definierar ett using direktiv och ett using alias för en klass:

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.

Från och med C# 12 kan du skapa alias för typer som tidigare var begränsade, inklusive tuppelns typer, pekartyper och andra osäkra typer. Mer information om de uppdaterade reglerna finns i funktionsspecifikationen.

Kvalificerad aliasmedlem

Aliaskvalificeraren :: för namnområdet ger explicit åtkomst till det globala namnområdet eller andra med hjälp av alias som kan döljas av andra entiteter.

Ser global:: till att namnområdessökningen för namnområdet efter :: token är relativ till det globala namnområdet. Annars måste token matchas mot ett alias med hjälp av och token som följer :: måste matchas till en typ i det aliaserade namnområdet. I följande exempel visas båda formulären:

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

Språkspecifikation för C#

Mer information finns i Använda direktiv i C#-språkspecifikationen. Språkspecifikationen är den slutgiltiga källan för C#-syntax och -användning.

Mer information om global användning av modifierare finns i funktionsspecifikationen för global användning – C# 10.

Se även