Freigeben über


Die using -Direktive

Mit der using-Anweisungen können Sie in einem Namespace definierte Typen verwenden, ohne den vollqualifizierten Namespace für diese anzugeben. In der unveränderten Form importiert die using-Anweisung alle Typen aus einem Namespace. Dies wird im folgenden Beispiel veranschaulicht:

using System.Text;

Sie können zwei Modifizierer auf eine using-Anweisung anwenden:

  • Der Modifizierer global hat die gleiche Wirkung wie das Hinzufügen derselben using-Anweisung zu jeder Quelldatei im Projekt. Dieser Modifizierer wurde in C# 10 eingeführt.
  • Der Modifizierer static importiert die Member von static und geschachtelte Typen aus einem einzelnen Typ, anstatt alle Typen in einem Namespace zu importieren.

Sie können beide Modifizierer kombinieren, um die statischen Elemente aus einem Typ in alle Quelldateien in Ihrem Projekt zu importieren.

Sie können auch einen Alias für einen Namespace oder einen Typ mit einer using-Aliasanweisung erstellen.

using Project = PC.MyCompany.Project;

Sie können den Modifizierer global in einer using-Aliasanweisung verwenden.

Hinweis

Das using-Schlüsselwort wird auch zum Erstellen von using-Anweisungen verwendet, mit denen sichergestellt wird, dass IDisposable-Objekte wie Dateien und Schriftarten richtig verarbeitet werden. Weitere Informationen zur using-Anweisung finden Sie unter using-Anweisung.

Ohne den Modifizierer global gilt eine using-Anweisung nur in der Datei, in der sie verwendet wird.

Die global using Direktive muss vor allen Namespace- und Typdeklarationen angezeigt werden. Alle globalen Using-Direktiven müssen in einer Quelldatei vor nicht globalen using Direktiven angezeigt werden.

Andere using Direktiven können angezeigt werden:

  • Am Anfang einer Quellcodedatei, vor Namespace- oder Typdeklarationen.
  • In jedem namespace mit blockierter Bereich, aber vor namespaces oder Typen, die in diesem Namespace deklariert sind.

Andernfalls wird ein Compilerfehler generiert.

Erstellen Sie eine using-Direktive, um die Typen in einem Namespace zu verwenden, ohne den Namespace angeben zu müssen. Eine using-Anweisung ermöglicht Ihnen nicht den Zugriff auf Namespaces, die im angegebenen Namespace geschachtelt sind. Gibt zwei Kategorien von Namespaces: benutzerdefinierte und systemdefinierte Namespaces. Benutzerdefinierte Namespaces sind Namespaces, die im Code definiert sind. Eine Liste der systemdefinierten Namespaces finden Sie unter .NET API-Browser.

Der global Modifizierer

Wenn Sie den Modifizierer global zu einer using-Anweisung hinzufügen, wird using auf alle kompilierten Dateien angewendet (üblicherweise auf ein ganzes Projekt). Die global using-Anweisung wurde in C# 10 hinzugefügt. Die Syntax sieht wie folgt aus:

global using <fully-qualified-namespace>;

Bei vollqualifiziertem Namespace handelt es sich um den vollqualifizierten Namen des Namespaces, auf dessen Typen ohne Angabe des Namespace verwiesen werden kann.

Eine global using-Anweisung kann am Anfang jeder Quellcodedatei eingefügt werden. Alle global using-Anweisungen in einer Datei müssen vor den folgenden Elementen eingefügt werden:

  • Alle using-Anweisungen ohne global-Modifizierer.
  • Alle Namespace- und Typdeklarationen in der Datei.

Sie können jeder Quelldatei Direktiven hinzufügen global using . In der Regel möchten Sie sie an einem einzigen Ort aufbewahren. Die Reihenfolge der global using-Anweisungen spielt weder in einzelnen noch in mehreren Dateien eine Rolle.

Der global Modifizierer kann mit dem static Modifizierer kombiniert werden. Der global Modifizierer kann auf eine using-Alias-Direktive angewendet werden. In beiden Fällen gilt die Anweisung für alle Dateien, die aktuell für die Kompilierung vorgesehen sind. Im folgenden Beispiel ermöglicht using die Verwendung aller Methoden, die in System.Math deklariert wurden, in allen Dateien des Projekts:

global using static System.Math;

Sie können einen Namespace auch global einschließen, indem Sie Ihrer Projektdatei ein <Using>-Element hinzufügen. Beispiel: <Using Include="My.Awesome.Namespace" />. Weitere Informationen finden Sie unter <Using>-Element.

Analysegeräte stellen Diagnosen aus, wenn Sie Direktiven an unterschiedlichen Stellen duplizieren global . Diese Analysegeräte informieren Sie auch darüber, ob Sie eine using Direktive für einen Namespace oder Typ hinzufügen, auf den bereits eine global using-Direktive verweist. Möglicherweise ist es einfacher, Ihre global Verwendungen zu verwalten, indem Sie sie in einer Datei im Projekt zusammenhalten.

Wichtig

Die C#-Vorlagen für .NET 6 verwenden Anweisungen der obersten Ebene. Ihre Anwendung passt möglicherweise nicht zum Code in diesem Artikel, wenn Sie bereits ein Upgrade auf .NET 6 durchgeführt haben. Weitere Informationen finden Sie im Artikel Neue C#-Vorlagen generieren Anweisungen auf oberster Ebene.

Das .NET 6 SDK fügt auch eine Reihe impliziter global using-Anweisungen für Projekte hinzu, die die folgenden SDKs verwenden:

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

Diese impliziten global using-Anweisungen enthalten die gängigsten Namespaces für den Projekttyp.

Weitere Informationen finden Sie im Artikel zum Thema „Implizite Verwendung von Anweisungen“.

Der static Modifizierer

Die using static-Anweisung nennt einen Typ, auf dessen statische Member und geschachtelte Typen Sie ohne Angabe eines Typnamens zugreifen können. Die Syntax sieht wie folgt aus:

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

Hierbei steht <fully-qualified-type-name> für den Namen des Typs, auf dessen statische Member und geschachtelte Typen verwiesen werden kann, ohne einen Typnamen anzugeben. Wenn Sie keinen vollqualifizierten Typnamen angeben (der vollständige Namespacename mit dem Typnamen), generiert C# den Compilerfehler CS0246: „The type or namespace name 'type/namespace' could not be found (are you missing a using directive or an assembly reference?)“ (Der Typ- oder Namespacename "type/namespace" wurde nicht gefunden (möglicherweise fehlt eine using-Anweisung oder ein Assemblyverweis)).

Die using static-Anweisung gilt für jeden Typ, der über statische Member (oder geschachtelte Typen) verfügt, auch wenn er ebenfalls über Instanzmember verfügt. Instanzmember können jedoch nur über die Typinstanz aufgerufen werden.

Sie können auf statische Member eines Typs zugreifen, ohne den Zugriff mit dem Typnamen zu qualifizieren:

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

Wenn Sie einen statischen Member aufrufen, geben Sie normalerweise den Typnamen zusammen mit dem Membernamen an. Das wiederholte Eingeben desselben Typnamens zum Aufrufen von Membern dieses Typs kann zu ausführlichem, verwirrendem Code führen. Die folgende Definition einer Circle-Klasse verweist z. B. auf mehrere Member der Klasse 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); }
   }
}

Da nicht mehr jedes Mal explizit auf die Klasse Math verwiesen werden muss, wenn auf einen Member verwiesen wird, erzeugt die using static-Anweisung deutlich übersichtlicheren Code:

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 importiert nur zugängliche statische Member und geschachtelte Typen, die im angegebenen Typ deklariert sind. Geerbte Member werden nicht importiert. Sie können aus jedem benannten Typ mit einer using static-Anweisung importieren, einschließlich Visual Basic-Module. Wenn F#-Funktionen der obersten Ebene in den Metadaten als statische Member eines benannten Typs angezeigt werden, dessen Name ein gültiger C#-Bezeichner ist, können die F#-Funktionen importiert werden.

using static macht Erweiterungsmethoden, die im angegebenen Typ deklariert sind, für die Erweiterungsmethodensuche verfügbar. Die Namen der Erweiterungsmethoden werden jedoch bei nicht qualifizierten Verweisen im Code nicht in den Gültigkeitsbereich importiert.

Methoden mit dem gleichen Namen, die aus verschiedenen Typen von verschiedenen statischen using static-Direktiven in der gleichen Kompilierungseinheit oder dem gleichen Namespace importiert wurden, bilden eine Methodengruppe. Die Überladungsauflösung innerhalb dieser Methodengruppen folgt den normalen C#-Regeln.

Im folgenden Beispiele wird die using static-Direktive verwendet, um die statischen Member der Klassen Console, Math und String zugänglich zu machen, ohne deren Typnamen angeben zu müssen.

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

Im Beispiel könnte die using static Direktive auch auf den Double Typ angewendet werden. Durch das Hinzufügen dieser Anweisung kann die Methode TryParse(String, Double) ohne Angabe eines Typnamens aufgerufen werden. Wenn Sie TryParse ohne Typnamen verwenden, wird allerdings weniger übersichtlicher Code generiert, da die using static-Anweisungen überprüft werden müssen, um zu bestimmen, welche TryParse-Methode eines numerischen Typs aufgerufen wird.

using static gilt auch für enum-Typen. Wenn Sie using static mit der Enumeration hinzufügen, wird der Typ nicht mehr benötigt, um die Enumerationsmember zu verwenden.

using static Color;

enum Color
{
    Red,
    Green,
    Blue
}

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

Der using Alias

Erstellen Sie eine using-Alias-Direktive, um das Qualifizieren eines Bezeichners in einen Namespace oder Typ zu vereinfachen. In jeder using-Anweisung muss der vollqualifizierte Namespace oder Typ unabhängig von den davor aufgeführten using-Anweisungen verwendet werden. In der Deklaration einer using-Direktive kann kein using-Alias verwendet werden. Beispielsweise verursacht das folgende Beispiel einen Compilerfehler:

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

Das folgende Beispiel zeigt, wie Sie einen using-Alias für einen Namespace definieren und verwenden:

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

Eine using-Aliasanweisung kann auf der rechten Seite nicht über einen offenen generischen Typ verfügen. Sie können zum Beispiel keinen using-Alias für List<T> erstellen, jedoch für List<int>.

Das folgende Beispiel zeigt, wie Sie eine using-Direktive und einen using-Alias für eine Klasse definieren:

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.

Ab C# 12 können Sie Aliase für Typen erstellen, die zuvor eingeschränkt waren, einschließlich Tupeltypen, Zeigertypen und anderen unsicheren Typen. Weitere Informationen zu den aktualisierten Regeln finden Sie in der Featurespezifikation.

Qualifiziertes Aliaselement

Der Namespacealiasqualifizierer bietet expliziten Zugriff auf den globalen Namespace oder andere Aliase, :: die potenziell von anderen Entitäten ausgeblendet werden.

Dadurch global:: wird sichergestellt, dass die Namespacesuche für den Namespace, der auf das :: Token folgt, relativ zum globalen Namespace ist. Andernfalls muss das Token in einen using-Alias aufgelöst werden, und das Token, das auf den :: folgenden Token folgt, muss in einen Typ in diesem aliasierten Namespace aufgelöst werden. Das folgende Beispiel zeigt beide Formulare:

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#-Sprachspezifikation

Weitere Informationen finden Sie unter using-Direktiven in der C#-Sprachspezifikation. Die Sprachspezifikation ist die verbindliche Quelle für die Syntax und Verwendung von C#.

Weitere Informationen zum global using-Modifizierer finden Sie in der Featurespezifikation für global using-Anweisungen (C# 10).

Weitere Informationen