Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Los programadores de C# usan un bloque try para crear particiones de código que podría verse afectado por una excepción.
Los bloques catch asociados se usan para controlar las excepciones resultantes. Un bloque finally contiene código que se ejecuta si se produce o no una excepción en el try
bloque, como liberar recursos asignados en el try
bloque. Un try
bloque requiere uno o varios bloques asociados catch
, o un finally
bloque, o ambos.
En los siguientes ejemplos, se muestra una sentencia try-catch
, una sentencia try-finally
y una sentencia 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 try
bloque sin un catch
o finally
provoca un error de compilador.
Bloques catch
Un catch
bloque puede especificar el tipo de excepción que se va a detectar. La especificación de tipo se denomina filtro de excepciones. El tipo de excepción debe derivarse de Exception. En general, no especifique Exception como el filtro de excepciones a menos que sepa cómo controlar todas las que puedan producirse en el bloque try
o que haya incluido una instrucción throw
al final del bloque catch
.
Se pueden encadenar varios catch
bloques con clases de excepción diferentes. Los catch
bloques se evalúan de arriba abajo en el código, pero solo se ejecuta un catch
bloque para cada excepción que se produce. El primer catch
bloque que especifica el tipo exacto o una clase base de la excepción iniciada se ejecuta. Si ningún catch
bloque especifica una clase de excepción coincidente, se selecciona un catch
bloque que no tiene ningún tipo, si hay uno presente en la instrucción . Es importante colocar primero bloques catch
con clases de excepción más específicas (es decir, las más derivadas).
Detectar excepciones cuando se cumplen las condiciones siguientes:
- Tiene una buena comprensión de por qué se puede producir la excepción y puede implementar una recuperación específica, como pedir al usuario que escriba un nuevo nombre de archivo al capturar un FileNotFoundException objeto.
- Puede crear y lanzar una nueva excepción más específica.
int GetInt(int[] array, int index) { try { return array[index]; } catch (IndexOutOfRangeException e) { throw new ArgumentOutOfRangeException( "Parameter index is out of range.", e); } }
- Quiere controlar parcialmente una excepción antes de pasarla para aumentar su control. En el ejemplo siguiente, se usa un
catch
bloque para agregar una entrada a un registro de errores antes de volver a iniciar la excepción.try { // Try to access a resource. } catch (UnauthorizedAccessException e) { // Call a custom error logging procedure. LogError(e); // Re-throw the error. throw; }
También puede especificar filtros de excepción para agregar una expresión booleana a una cláusula catch. Los filtros de excepción indican que una cláusula catch específica coincide solo cuando esa condición es verdadera. En el ejemplo siguiente, ambas cláusulas catch usan la misma clase de excepción, pero se comprueba una condición adicional para crear un mensaje de error diferente:
int GetInt(int[] array, int index)
{
try
{
return array[index];
}
catch (IndexOutOfRangeException e) when (index < 0)
{
throw new ArgumentOutOfRangeException(
"Parameter index cannot be negative.", e);
}
catch (IndexOutOfRangeException e)
{
throw new ArgumentOutOfRangeException(
"Parameter index cannot be greater than the array size.", e);
}
}
Un filtro de excepción que siempre devuelve false
se puede usar para examinar todas las excepciones, pero no procesarlas. Un uso típico es registrar excepciones:
public class ExceptionFilter
{
public static void Main()
{
try
{
string? s = null;
Console.WriteLine(s.Length);
}
catch (Exception e) when (LogException(e))
{
}
Console.WriteLine("Exception must have been handled");
}
private static bool LogException(Exception e)
{
Console.WriteLine($"\tIn the log routine. Caught {e.GetType()}");
Console.WriteLine($"\tMessage: {e.Message}");
return false;
}
}
El LogException
método siempre devuelve false
, ninguna catch
cláusula que use este filtro de excepciones coincide. La cláusula catch puede ser general, usando System.Exception, y cláusulas posteriores pueden procesar clases de excepciones más específicas.
Bloques Finally
Un finally
bloque le permite limpiar las acciones que se realizan en un try
bloque. Si está presente, el finally
bloque se ejecuta en último lugar, después del try
bloque y de cualquier bloque coincidente catch
. Un finally
bloque siempre se ejecuta, tanto si se produce una excepción como si se encuentra un catch
bloque que coincida con el tipo de excepción.
Los bloques finally
pueden usarse para liberar recursos como secuencias de archivo, conexiones de base de datos y controladores de gráficos sin necesidad de esperar a que el recolector de elementos no utilizados en tiempo de ejecución finalice los objetos.
En el ejemplo siguiente, el finally
bloque se usa para cerrar un archivo que se abre en el try
bloque . Observe que el estado del identificador de archivo se comprueba antes de cerrar el archivo. Si el try
bloque no puede abrir el archivo, el identificador de archivo todavía tiene el valor null
y el finally
bloque no intenta cerrarlo. En su lugar, si el archivo se abre correctamente en el try
bloque, el finally
bloque cierra el archivo abierto.
FileStream? file = null;
FileInfo fileinfo = new System.IO.FileInfo("./file.txt");
try
{
file = fileinfo.OpenWrite();
file.WriteByte(0xF);
}
finally
{
// Check for null because OpenWrite might have failed.
file?.Close();
}
Especificación del lenguaje C#
Para obtener más información, vea Excepciones y la instrucción try en la especificación del lenguaje C#. La especificación del lenguaje es el origen definitivo de la sintaxis y el uso de C#.