C# Language Uso de los fundamentos de la declaración


Ejemplo

using azúcar sintáctica le permite garantizar que un recurso se limpie sin necesidad de un bloque explícito de try-finally . Esto significa que su código será mucho más limpio y no perderá recursos no administrados.

El patrón estándar de limpieza de Dispose , para los objetos que implementan la interfaz IDisposable (que la clase base Stream FileStream hace en .NET):

int Foo()
{
    var fileName = "file.txt";

    {
        FileStream disposable = null;

        try
        {
            disposable = File.Open(fileName, FileMode.Open);

            return disposable.ReadByte();
        }
        finally
        {
            // finally blocks are always run
            if (disposable != null) disposable.Dispose();
        }
    }
}

using simplifica su sintaxis al ocultar el try-finally explícito try-finally :

int Foo()
{
    var fileName = "file.txt";

    using (var disposable = File.Open(fileName, FileMode.Open))
    {
        return disposable.ReadByte();
    }
    // disposable.Dispose is called even if we return earlier
}

Al igual que, finally bloques siempre se ejecutan independientemente de los errores o devoluciones, using siempre las llamadas Dispose() , incluso en caso de error:

int Foo()
{
    var fileName = "file.txt";

    using (var disposable = File.Open(fileName, FileMode.Open))
    {
        throw new InvalidOperationException();
    }
    // disposable.Dispose is called even if we throw an exception earlier
}

Nota: dado que se garantiza que Dispose se llame independientemente del flujo de código, es una buena idea asegurarse de que Dispose nunca arroje una excepción cuando implemente IDisposable . De lo contrario, una excepción real quedaría anulada por la nueva excepción que resultaría en una pesadilla de depuración.

Volviendo de usar bloque

using ( var disposable = new DisposableItem() )
{
    return disposable.SomeProperty;
}

Debido a la semántica de try..finally a la que se traduce el bloque de using , la declaración de return funciona como se esperaba: el valor de retorno se evalúa antes de que finally se ejecute el bloque y se elimine el valor. El orden de evaluación es el siguiente:

  1. Evaluar el cuerpo de try
  2. Evaluar y almacenar en caché el valor devuelto
  3. Ejecutar finalmente el bloque
  4. Devuelve el valor de retorno en caché

Sin embargo, no puede devolver la variable disposable sí misma, ya que contendría una referencia desechada no válida; consulte el ejemplo relacionado .