Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Tipp
Neu bei der Entwicklung von Software? Beginnen Sie zuerst mit den Lernprogrammen " Erste Schritte ". Sie führen Namespaces und using Direktiven ein, während Sie Ihre ersten Programme schreiben.
Haben Sie Erfahrung in einer anderen Sprache? Namespaces in C# funktionieren ähnlich wie Pakete in Java oder Modulen in Python. Überspringen Sie zum benötigten Abschnitt mit der Syntax.
Namespacedeklarationen und using Direktiven sind verwandte Sprachfeatures. Eine Namespacedeklaration fügt Ihre Typen in eine organisierte Struktur ein. Ein Namespace gruppiert verwandte Typen zusammen und verhindert Namenskonflikte. Mit einer using-Direktive kann Ihr Programm diese Typen unter ihren einfachen Namen nutzen. Sie müssen bei jeder Verwendung nicht den vollständigen Namespacepfad eingeben.
Sie haben bereits Namespaces in jedem von Ihnen geschriebenen C#-Programm verwendet. Jeder .NET-Typ gehört zu einem Namespace, und jede using Direktive am Anfang einer Datei verweist auf einen. Beispielsweise gehören Console und Math zum System Namespace, sodass ihre vollqualifizierten Namen System.Console und System.Math sind. Sammlungstypen wie List<T> und Dictionary<TKey, TValue> gehören zu System.Collections.Generic. Mit einer einzigen using Direktive für einen dieser Namespaces können Sie anhand ihrer einfachen Namen auf alle zugehörigen Typen verweisen. Sie schreiben List<T> anstelle von System.Collections.Generic.List<T>, überall wo Sie es verwenden.
Dieser Artikel enthält weitere Hintergrundinformationen zur Funktionsweise von Namespaces und using Direktiven und zeigt Beispiele für Muster, die Sie bereits in .NET-Bibliotheken gefunden haben.
Ein Namespace enthält Typen. Jeder .NET-Typ gehört zu einem Namespace. Angenommen System.Threading.Tasks.Task, der Typ Task gehört zum System.Threading.Tasks Namespace.
Es empfiehlt sich, verwandte oder ähnliche Typen im selben Namespace zu gruppieren, und das macht .NET mit den bereitgestellten Typen. Der System.Collections.Generic Namespace enthält sammlungsbezogene Typen, und der System.IO Namespace enthält Typen verwandter Lese- und Schreibdateien, Verzeichnisse und Daten. Der System Namespace enthält grundlegende Typen wie Math, DateTime, und Console.
Das folgende Beispiel zeigt, wie Namespaces mit using Direktiven in einer typischen C#-Datei zusammenarbeiten:
using System.Globalization;
namespace MyApp.Services;
class Greeter
{
public string Greet(string name)
{
var culture = CultureInfo.CurrentCulture;
return $"Hello, {name}! Culture: {culture.Name}";
}
}
Im vorherigen Beispiel bedeutet die using Direktive, dass Sie den System.Globalization.CultureInfo unter dem Namen CultureInfo verwenden können, ohne den vollständigen Namen von System.Globalization.CultureInfo anzugeben. Die namespace Direktive deklariert, dass die Greeter Klasse Teil des MyApp.Services Namespace ist. Der vollqualifizierte Name lautet MyApp.Services.Greeter.
Namespacedeklarationen
Eine Namespacedeklaration weist Ihren Typen eine benannte Gruppe zu. Jeder Typ, den Sie schreiben, sollte zu einem Namespace gehören. Der Namespacename spiegelt in der Regel die Ordnerstruktur Ihres Projekts wieder. Beispielsweise gehören Typen in einem Services/Payments Ordner häufig zum MyApp.Services.Payments Namespace.
Namespaces verwenden den Operator . zum Ausdrücken der Hierarchie, wie System.Collections.Generic. Namespacenamen müssen gültige C# -Bezeichnernamen sein.
Dateibereichsnamespaces
Verwenden Sie die Syntax mit Dateibereich , wenn alle Typen in einer Datei zum gleichen Namespace gehören. Fügen Sie nach der Namespacedeklaration ein Semikolon hinzu, und es gilt für die gesamte Datei. Sie benötigen keine zusätzlichen geschweiften Klammern oder Einzug:
namespace MyApp.Models;
class Customer
{
public required string Name { get; init; }
public string? Email { get; init; }
public override string ToString() => $"{Name} ({Email ?? "no email"})";
}
Dateibereichsnamespaces reduzieren die Schachtelung und vereinfachen das Lesen von Dateien. Pro Datei kann nur eine Namespace-Deklaration mit Dateibezug vorhanden sein.
Tipp
Verwenden Sie dateigebundene Namespaces in neuem Code. Die meisten .NET-Vorlagen und Codeanalysatoren empfehlen diesen Stil.
Blockbereichsnamespaces
Verwenden Sie die blockbereichsspezifische Syntax, wenn Sie mehrere Namespaces in derselben Datei deklarieren müssen. Diese Formatvorlage fügt eine zusätzliche Ebene des Einzugs hinzu.
Von Bedeutung
Es wird als falsch angesehen, mehrere Namespaces in derselben Datei zu deklarieren. Das häufigere Szenario besteht darin, dateibezogene Namespaces zu verwenden.
Der folgende Codeausschnitt ist ein Beispiel für einen blockbezogenen Namespace:
namespace MyApp.Models
{
class Product
{
public required string Name { get; init; }
public decimal Price { get; init; }
public override string ToString() => $"{Name}: {Price:C}";
}
}
Verwendungsdirektiven
Ohne eine using Direktive müssen Sie auf jeden Typ mit seinem vollqualifizierten Namen, also dem vollständigen Namespacepfad plus dem Typnamen verweisen.
static void ShowFullyQualified()
{
// Without a using directive, use the fully qualified name:
System.Console.WriteLine("Hello from fully qualified name!");
}
Eine using Direktive oben in einer Datei importiert einen Namespace, sodass Sie dessen Typen mit ihren einfachen Namen verwenden können:
static void ShowShortName()
{
// With 'using System;' (or implicit usings enabled), use the short name:
Console.WriteLine("Hello from short name!");
}
Weitere Informationen finden Sie in der using Direktive.
Globale Verwendung von Direktiven
Wenn Sie die gleichen using Direktiven in jeder Datei schreiben, können Sie globale using-Direktiven verwenden, um diese einmal für das gesamte Projekt zu deklarieren. Platzieren Sie sie in einer beliebigen Datei. Viele Teams erstellen eine dedizierte GlobalUsings.cs Datei:
global using System.Text;
global using System.Text.Json;
Nach dem Deklarieren einer globalen Verwendung kann jede Datei im Projekt auf Typen aus diesem Namespace verweisen, indem einfache Namen ohne zusätzliche using Direktive verwendet werden.
Implizite Verwendungen
Das .NET SDK generiert automatisch globale using-Direktiven für die am häufigsten verwendeten Namespaces, basierend auf dem Projekttyp. Aktivieren Sie implizite Verwendungen, indem Sie <ImplicitUsings>enable</ImplicitUsings> in Ihrer Projektdatei einstellen. Beispielsweise importiert ein Konsolen-App-Projekt automatisch System, System.Collections.Generic, System.IO, System.Linq, System.Threading und System.Threading.Tasks. Die aktuelle SDK ermöglicht ImplicitUsings beim Erstellen eines neuen Projekts mithilfe dotnet new.
Weitere Informationen finden Sie unter Implizite Using-Direktiven.
Statisch mithilfe von Direktiven
Eine static using Direktive importiert die statischen Member eines Typs, sodass Sie sie ohne das Präfix des Typnamens aufrufen können:
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;
}
Statische using-Anweisungen eignen sich gut für Hilfsklassen wie Math und Console, die Sie häufig aufrufen.
Typen- und Namespaces-Aliase
Ein using Alias erstellt einen Kurznamen für einen Typ oder Namespace. Aliase sind nützlich für lange generische Typen, das Auflösen von Namenskonflikten und die Verbesserung der Lesbarkeit:
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;
}
}
Ab C# 12 können Sie jeden beliebigen Typen umbenennen, einschließlich Tupel und Zeigertypen.
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);
}
}
Für komplexere Szenarien, in denen zwei Assemblys denselben vollqualifizierten Typnamen definieren, verwenden Sie extern alias, um zwischen ihnen zu unterscheiden.