using-Anweisung (C#-Referenz)

Bietet eine praktische Syntax, die den ordnungsgemäßen Einsatz von IDisposable-Objekten sicherstellt Ab C# 8.0 stellt die using-Anweisung die korrekte Verwendung von IAsyncDisposable-Objekten sicher.

Beispiel

Im folgenden Beispiel wird veranschaulicht, wie Sie die Anweisung using verwenden.

string manyLines=@"This is line one
This is line two
Here is line three
The penultimate line is line four
This is the final, fifth line.";

using (var reader = new StringReader(manyLines))
{
    string? item;
    do {
        item = reader.ReadLine();
        Console.WriteLine(item);
    } while(item != null);
}

Ab C# 8,0 können Sie die folgende alternative Syntax für die using-Anweisung verwenden, die keine geschweiften Klammern erfordert:

string manyLines=@"This is line one
This is line two
Here is line three
The penultimate line is line four
This is the final, fifth line.";

using var reader = new StringReader(manyLines);
string? item;
do {
    item = reader.ReadLine();
    Console.WriteLine(item);
} while(item != null);

Hinweise

File und Font sind Beispiele für verwaltete Typen, die auf nicht verwaltete Ressourcen zugreifen (in diesem Fall Dateihandles und Gerätekontexte). Es gibt viele andere Arten von nicht verwalteten Ressourcen und Klassenbibliothekstypen, die sie einschließen. Alle Typen dieser Art müssen die IDisposable-Schnittstelle oder die IAsyncDisposable-Schnittstelle implementieren.

Wenn die Lebensdauer eines IDisposable-Objekts auf eine einzige Methode beschränkt ist, sollten Sie es in der using-Anweisung deklarieren und instanziieren. Die using-Anweisung ruft die Methode Dispose ordnungsgemäß für das Objekt auf. Wenn Sie sie, wie vorher gezeigt, verwenden, führt dies auch dazu, dass das Objekt den gültigen Bereich verlässt, sobald Dispose aufgerufen wird. Innerhalb des using-Blocks ist das Objekt schreibgeschützt und kann nicht geändert oder neu zugewiesen werden. Wenn das Objekt IAsyncDisposable anstelle von IDisposable implementiert, ruft die using-Anweisung die DisposeAsync-Methode und den awaits-Operator für die zurückgegebene ValueTask-Klasse auf. Weitere Informationen zu IAsyncDisposable finden Sie unter Implementieren einer DisposeAsync-Methode.

Mit der Anweisung using wird sichergestellt, dass Dispose (oder DisposeAsync) aufgerufen wird, selbst wenn eine Ausnahme im using-Block auftritt. Sie können das gleiche Ergebnis erzielen, indem Sie das Objekt in einen try-Block einfügen und dann Dispose (oder DisposeAsync) in einem finally-Block aufrufen. So übersetzt der Compiler die Anweisung using. Das vorherige Codebeispiel wird zur Kompilierzeit auf den folgenden Code erweitert (beachten Sie die zusätzlichen geschweiften Klammern zum Erstellen des eingeschränkten Gültigkeitsbereichs für das Objekt):

string manyLines=@"This is line one
This is line two
Here is line three
The penultimate line is line four
This is the final, fifth line.";

{
    var reader = new StringReader(manyLines);
    try {
        string? item;
        do {
            item = reader.ReadLine();
            Console.WriteLine(item);
        } while(item != null);
    } finally
    {
        reader?.Dispose();
    }
}

Die neuere Syntax der using-Anweisung wird in ähnlichen Code übersetzt. Der try-Block wird geöffnet, in dem die Variable deklariert wird. Der finally-Block wird am Ende des einschließenden Blocks hinzugefügt, in der Regel am Ende einer Methode.

Weitere Informationen über die Anweisung try-finally finden Sie im Artikel zu try-finally.

Mehrere Instanzen eines Typs können wie im folgenden Beispiel gezeigt in einer einzelnen using-Anweisung deklariert werden. Beachten Sie, dass Sie Variablen mit impliziten Typen (var) nicht verwenden können, wenn Sie mehrere Variablen in einer einzelnen Anweisung deklarieren:

string numbers=@"One
Two
Three
Four.";
string letters=@"A
B
C
D.";

using (StringReader left = new StringReader(numbers),
    right = new StringReader(letters))
{
    string? item;
    do {
        item = left.ReadLine();
        Console.Write(item);
        Console.Write("    ");
        item = right.ReadLine();
        Console.WriteLine(item);
    } while(item != null);
}

Sie können wie im folgenden Beispiel gezeigt auch mehrere Deklarationen desselben Typs mithilfe der neuen Syntax kombinieren, die mit C# 8 eingeführt wurde:

string numbers=@"One
Two
Three
Four.";
string letters=@"A
B
C
D.";

using StringReader left = new StringReader(numbers),
    right = new StringReader(letters);
string? item;
do {
    item = left.ReadLine();
    Console.Write(item);
    Console.Write("    ");
    item = right.ReadLine();
    Console.WriteLine(item);
} while(item != null);

Sie können das Ressourcenobjekt instanziieren und die Variable an die using-Anweisung übergeben. Diese Vorgehensweise wird jedoch nicht empfohlen. In diesem Fall verbleibt das Objekt im Gültigkeitsbereich, nachdem das Steuerelement den using-Block verlassen hat, obwohl es wahrscheinlich keinen Zugriff auf dessen nicht verwaltete Ressourcen hat. Das heißt, dass es nicht mehr vollständig initialisiert wird. Wenn Sie versuchen, das Objekt außerhalb des using-Blocks zu verwenden, riskieren Sie, dass eine Ausnahme ausgelöst wird. Aus diesem Grund ist es besser, das Objekt in der using-Anweisung zu instanziieren und dessen Bereich auf den using-Block zu begrenzen.

string manyLines=@"This is line one
This is line two
Here is line three
The penultimate line is line four
This is the final, fifth line.";

var reader = new StringReader(manyLines);
using (reader)
{
    string? item;
    do {
        item = reader.ReadLine();
        Console.WriteLine(item);
    } while(item != null);
}
// reader is in scope here, but has been disposed

Weitere Informationen zum Verwerfen von IDisposable-Objekten finden Sie unter Verwenden von Objekten, die IDisposable implementieren.

C#-Sprachspezifikation

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

Siehe auch