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

Die verwendungsdeklaration, die in C# 8.0 eingeführt wurde, erfordert keine Klammern:

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 einzelne Methode beschränkt ist, sollten Sie es in der using Anweisung oder using Deklaration deklarieren und instanziieren. Die using Deklaration ruft die Dispose Methode für das Objekt auf die richtige Weise auf, wenn sie außerhalb des Bereichs geht. Die using Anweisung bewirkt, dass das Objekt selbst außerhalb des Bereichs liegt, sobald er Dispose aufgerufen wird. Innerhalb des using-Blocks ist das Objekt schreibgeschützt und kann nicht geändert oder neu zugewiesen werden. Eine Variable, die mit einer using Deklaration deklariert wird, ist schreibgeschützt. Wenn das Objekt anstelle des Objekts implementiert IAsyncDisposable wird, ruft entweder using das Formular die DisposeAsync und awaits die zurückgegebene ValueTask.IDisposable Weitere Informationen zu IAsyncDisposable finden Sie unter Implementieren einer DisposeAsync-Methode.

Beide using Formulare stellen sicher, dass Dispose (oder DisposeAsync) aufgerufen wird, auch wenn eine Ausnahme innerhalb des using Blocks auftritt. Sie können dasselbe Ergebnis erzielen, indem Sie das Objekt in einen Block setzen und dann (oder DisposeAsync) in einem finallytry Block aufrufen Dispose ; tatsächlich ist dies, wie die using Anweisung und die using Deklaration vom Compiler übersetzt werden. 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 mehrere Deklarationen desselben Typs mithilfe der mit C# 8 eingeführten Deklarationssyntax kombinieren, wie im folgenden Beispiel gezeigt:

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