Instrucción using: asegúrese del uso correcto de objetos descartables

La instrucción using garantiza el uso correcto de una instancia IDisposable:

var numbers = new List<int>();
using (StreamReader reader = File.OpenText("numbers.txt"))
{
    string line;
    while ((line = reader.ReadLine()) is not null)
    {
        if (int.TryParse(line, out int number))
        {
            numbers.Add(number);
        }
    }
}

Cuando el control sale del bloque de la instrucción using, se elimina una instancia IDisposable adquirida. En concreto, la instrucción using garantiza que una instancia descartable se elimine incluso si se produce una excepción dentro del bloque de la instrucción using. En el ejemplo anterior, se cierra un archivo abierto después de procesar todas las líneas.

Use la instrucción await using para usar correctamente una instancia IAsyncDisposable:

await using (var resource = new AsyncDisposableExample())
{
    // Use the resource
}

Para obtener más información sobre cómo usar las instancias IAsyncDisposable, vea la sección Uso de la eliminación asincrónica del artículo Implementación de un método DisposeAsync.

También puede usar una usingdeclaración que no requiera llaves:

static IEnumerable<int> LoadNumbers(string filePath)
{
    using StreamReader reader = File.OpenText(filePath);
    
    var numbers = new List<int>();
    string line;
    while ((line = reader.ReadLine()) is not null)
    {
        if (int.TryParse(line, out int number))
        {
            numbers.Add(number);
        }
    }
    return numbers;
}

Cuando se declara en una declaración using, una variable local se elimina al final del ámbito en el que se declara. En el ejemplo anterior, la eliminación se produce al final de un método.

Una variable declarada por la instrucción using o declaración es readonly. No se puede reasignar ni pasar como parámetro ref o out.

Puede declarar varias instancias del mismo tipo en una instrucción using, tal como se muestra en el ejemplo siguiente:

using (StreamReader numbersFile = File.OpenText("numbers.txt"), wordsFile = File.OpenText("words.txt"))
{
    // Process both files
}

Cuando se declaran varias instancias en una instrucción using, se eliminan en orden inverso al de declaración.

También puede usar la instrucción y la declaración using con una instancia de una estructura ref que se ajuste al patrón descartable. Es decir, tiene una instancia o un método Dispose de extensión, que es accesible, no tiene parámetros y tiene un tipo de valor devuelto void.

La instrucción using también puede tener el siguiente formato:

using (expression)
{
    // ...
}

donde expression genera una instancia descartable. En el siguiente ejemplo se muestra que:

StreamReader reader = File.OpenText(filePath);

using (reader)
{
    // Process file content
}

Advertencia

En el ejemplo anterior, después de que el control salga de la instrucción using, una instancia descartable permanece en el ámbito aunque ya está desechada. Si usa más esa instancia, podría encontrar una excepción, por ejemplo, ObjectDisposedException. Por eso se recomienda declarar una variable descartable dentro de la instrucción using o con la declaración using.

Especificación del lenguaje C#

Para obtener más información, vea la sección Using de la especificación del lenguaje C# y la nota de propuesta sobre "uso basado en patrones" y "uso de declaraciones".

Consulte también