Compartir a través de


Control de excepciones (Guía de programación de C#)

Los programadores de C# usan bloques try para separar el código al que puede afectar una excepción. Los bloques catch asociados se utilizan para controlar las excepciones resultantes. Un bloque finally contiene código que se ejecuta con independencia de que se produzca o no una excepción en el bloque try, como liberar recursos asignados en el bloque try. Un bloque try requiere tener asociados uno o más bloques catch o un bloque finally, o bien ambas opciones.

En los ejemplos siguientes se muestra una instrucción try-catch, una instrucción try-finally y una instrucción try-catch-finally.

try
{
    // Code to try goes here.
}
catch (SomeSpecificException ex)
{
    // Code to handle the exception goes here. 
    // Only catch exceptions that you know how to handle. 
    // Never catch base class System.Exception without 
    // rethrowing it at the end of the catch block.
}
try
{
    // Code to try goes here.
}
finally
{
    // Code to execute after the try block goes here.
}
try
{
    // Code to try goes here.
}
catch (SomeSpecificException ex)
{
    // Code to handle the exception goes here.
}
finally
{
    // Code to execute after the try (and possibly catch) blocks  
    // goes here.
}

Un bloque try sin un bloque catch o finally produce un error del compilador.

Bloques Catch

Un bloque catch puede especificar el tipo de excepción que se detectará. La especificación de tipo se denomina filtro de excepción. El tipo de excepción debe derivarse de Exception. En general, no especifique Exception como filtro de excepción a menos que sepa cómo controlar todas las excepciones que puedan producirse en el bloque try o bien haya incluido una instrucción throw al final del bloque catch.

Se pueden encadenar varios bloques catch con filtros de excepción diferentes. Los bloques catch se evalúan de arriba abajo en el código, pero solo se ejecuta un bloque catch para cada excepción iniciada. Se ejecutará el primer bloque catch que especifica el tipo exacto o una clase base de la excepción que se haya producido. Si ningún bloque catch especifica un filtro coincidente de la excepción, un bloque catch que no tiene un filtro se selecciona, si hay alguno presente en la instrucción. Es importante colocar los bloques catch con los tipos de excepción más concretos (es decir, más derivados) en primer lugar.

Debería detectar excepciones cuando se cumplen las condiciones siguientes:

  • Comprende claramente por qué puede producirse la excepción y puede implementar una recuperación concreta, como pedir al usuario que escriba un nuevo nombre de archivo cuando se detecta un objeto FileNotFoundException.

  • Pueda crear y producir una excepción nueva más específica.

    int GetInt(int[] array, int index)
    {
        try
        {
            return array[index];
        }
        catch(System.IndexOutOfRangeException e)
        {
            throw new System.ArgumentOutOfRangeException(
                "Parameter index is out of range.");
        }
    }
    
  • Desea controlar parcialmente una excepción antes de pasarla para realizar un control adicional. En el ejemplo siguiente, se usa un bloque catch para agregar una entrada a un registro de errores antes de volver a producir la excepción.

    try
    {
        // Try to access a resource.
    }
    catch (System.UnauthorizedAccessException e)
    {
        // Call a custom error logging procedure.
        LogError(e);
        // Re-throw the error. 
        throw;     
    }
    

Bloques Finally

Un bloque finally permite limpiar las acciones que se realizan en un bloque try. Si está presente, el bloque finally se ejecuta en último lugar, después del bloque try y cualquier bloque catch coincidente. Un bloque finally se ejecuta siempre, sin tener en cuenta si se produce una excepción o si se encuentra un bloque catch que coincida con el tipo de excepción.

El bloque finally se puede utilizar para liberar recursos como secuencias de archivos, conexiones de base de datos y controladores de gráficos sin esperar a que el recolector de elementos no utilizados del motor en tiempo de ejecución finalice los objetos. Para obtener más información, consulte using (Instrucción, Referencia de C#).

En el ejemplo siguiente, el bloque finally se usa para cerrar un archivo que se abre en el bloque try. Observe que se comprueba el estado del identificador del archivo antes de cerrarlo. Si el bloque try no puede abrir el archivo, el identificador de archivos seguirá teniendo el valor null y el bloque finally no intenta cerrarlo. Como alternativa, si el archivo se abre correctamente en el bloque try, el bloque finally cierra el archivo abierto.

System.IO.FileStream file = null;
System.IO.FileInfo fileinfo = new System.IO.FileInfo("C:\\file.txt");
try
{
    file = fileinfo.OpenWrite();
    file.WriteByte(0xF);
}
finally
{
    // Check for null because OpenWrite might have failed. 
    if (file != null)
    {
        file.Close();
    }
}

Especificación del lenguaje C#

Para obtener más información, consulte la Especificación del lenguaje C#. La especificación del lenguaje es la fuente definitiva de la sintaxis y el uso de C#.

Vea también

Referencia

Excepciones y control de excepciones (Guía de programación de C#)

try-catch (Referencia de C#)

try-finally (Referencia de C#)

try-catch-finally (Referencia de C#)

using (Instrucción, Referencia de C#)

Conceptos

Guía de programación de C#

Otros recursos

Referencia de C#