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

Actualización: noviembre 2007

Los programadores de C# utilizan bloques try para separar el código al que puede afectar una excepción y bloques catch para controlar las excepciones resultantes. Un bloque finally se puede utilizar para ejecutar código independientemente de que se produzca una excepción. Esta situación es necesaria en ocasiones, porque el código que sigue a una construcción try/catch no se ejecutará si se produce una excepción. Un bloque try se debe utilizar con un bloque catch o finally, y puede incluir varios bloques catch. Por ejemplo:

try
{
    // Code to try here.
}
catch (SomeSpecificException ex)
{
    // Code to handle exception here.
    // Only catch exceptions 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 here.
}
finally
{
    // Code to execute after try here.
}
try
{
    // Code to try here.
}
catch (SomeSpecificException ex)
{
    // Code to handle exception here.
}
finally
{
    // Code to execute after try (and possibly catch) here.
}

Una instrucción try sin un bloque catch o finally provocará un error del compilador.

Bloques Catch

Un bloque catch puede especificar un tipo de excepción que se detectará. Este tipo se denomina filtro de excepciones y debe ser un tipo derivado de Exception. En general, no especifique Exception en un bloque catch a menos que sepa con seguridad cómo controlar todas las excepciones que puedan producirse en el bloque try o que incluya una instrucción throw al final del bloque catch.

Se pueden encadenar varios bloques catch con filtros de excepción diferentes. Los bloques catch múltiples se evalúan de arriba a abajo, pero sólo se ejecuta un bloque catch para cada excepción iniciada. Se ejecutará el primer bloque catch que especifique el tipo exacto o una clase base de la excepción que se haya producido. Si ningún bloque catch especifica un filtro de excepción coincidente, se ejecutará un bloque catch sin filtro (si existe alguno). Es importante colocar los bloques catch con las clases de excepción más concretas (es decir, más derivadas) en primer lugar.

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

  • Tenga un conocimiento específico del motivo por el que se produjo la excepción y pueda implementar una recuperación concreta, por ejemplo, detectar una excepción FileNotFoundException y solicitar al usuario que escriba un nuevo nombre de archivo.

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

    int GetInt(int[] array, int index)
    {
        try
        {
            return array[index];
        }
        catch(System.IndexOutOfRangeException e)
        {
            throw new System.ArgumentOutOfRangeException(
                "Parameter index is out of range.");
        }
    }
    
  • Para controlar parcialmente una excepción. Por ejemplo, podría utilizarse un bloque catch para agregar una entrada a un registro de errores, pero después producir otra vez la excepción para habilitar el control posterior de la misma. Por ejemplo:

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

Bloques Finally

Un bloque finally habilita la limpieza de acciones en un bloque try. Si el bloque finally está presente, se ejecuta después de los bloques try y catch. 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 este ejemplo, el bloque finally se utiliza para cerrar un archivo abierto en el bloque try. Observe que se comprueba el estado del identificador del archivo antes de cerrarlo. Si el bloque try no abrió el archivo, el identificador de archivo seguirá establecido en null. Opcionalmente, si se abre correctamente el archivo y no se produce una excepción, el bloque finally se ejecutará y cerrará 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, vea las secciones siguientes de Especificación del lenguaje C#:

  • 16 Excepciones

  • 8.9.5 La instrucción throw

  • 8.10 La instrucción try

Vea también

Conceptos

Guía de programación de C#

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#)

Otros recursos

Referencia de C#