Oharra
Baimena behar duzu orria atzitzeko. Direktorioetan saioa has dezakezu edo haiek alda ditzakezu.
Baimena behar duzu orria atzitzeko. Direktorioak alda ditzakezu.
Las excepciones se usan para indicar que se ha producido un error al ejecutar el programa. Los objetos de excepción que describen un error se crean y, a continuación, se lanzan con la throw
instrucción o expresión. A continuación, el tiempo de ejecución busca el controlador de excepciones más compatible.
Los programadores deben producir excepciones cuando se cumplen una o varias de las condiciones siguientes:
El método no puede completar su funcionalidad definida. Por ejemplo, si un parámetro de un método tiene un valor no válido:
static void CopyObject(SampleClass original) { _ = original ?? throw new ArgumentException("Parameter cannot be null", nameof(original)); }
Se realiza una llamada inapropiada a un objeto, en función del estado del objeto. Un ejemplo podría estar intentando escribir en un archivo de solo lectura. En los casos en que el estado de un objeto no permite una operación, lance una instancia de InvalidOperationException o un objeto basado en una derivación de esta clase. El código siguiente es un ejemplo de un método que produce un InvalidOperationException objeto :
public class ProgramLog { FileStream logFile = null!; public void OpenLog(FileInfo fileName, FileMode mode) { } public void WriteLog() { if (!logFile.CanWrite) { throw new InvalidOperationException("Logfile cannot be read-only"); } // Else write data to the log and return. } }
Cuando un argumento a un método produce una excepción. En este caso, se debe detectar la excepción original y se debe crear una ArgumentException instancia. La excepción original debe pasarse al constructor de ArgumentException como parámetro InnerException :
static int GetValueFromArray(int[] array, int index) { try { return array[index]; } catch (IndexOutOfRangeException e) { throw new ArgumentOutOfRangeException( "Parameter index is out of range.", e); } }
Nota:
En el ejemplo anterior se muestra cómo usar la
InnerException
propiedad . Se simplifica intencionadamente. En la práctica, debe comprobar que un índice está dentro del rango antes de usarlo. Puede usar esta técnica de encapsular una excepción cuando un miembro de un parámetro produce una excepción que no se pudo prever antes de llamar al miembro.
Las excepciones contienen una propiedad denominada StackTrace. Esta cadena contiene el nombre de los métodos de la pila de llamadas actual, junto con el nombre de archivo y el número de línea donde se produjo la excepción para cada método. Common Language Runtime (CLR) crea automáticamente un objeto StackTrace desde el punto de la instrucción throw
, de manera que todas las excepciones se deben producir desde el punto en el que debe comenzar el seguimiento de la pila.
Todas las excepciones contienen una propiedad denominada Message. Esta cadena debe establecerse para explicar el motivo de la excepción. La información que es confidencial para la seguridad no debe colocarse en el texto del mensaje. Además de Message, ArgumentException contiene una propiedad denominada ParamName que debe establecerse en el nombre del argumento que hizo que se lanzara la excepción. En un establecedor de propiedades, ParamName debe establecerse a value
.
Los métodos públicos y protegidos arrojan excepciones siempre que no puedan completar sus funciones previstas. La clase de excepción lanzada es la excepción más específica disponible que se ajusta a las condiciones de error. Estas excepciones deben documentarse como parte de la funcionalidad de clase, y las clases o actualizaciones derivadas de la clase original deben conservar el mismo comportamiento para la compatibilidad con versiones anteriores.
Cosas que se deben evitar al lanzar excepciones
En la lista siguiente se identifican las prácticas que se deben evitar al iniciar excepciones:
- No use excepciones para cambiar el flujo de un programa como parte de la ejecución ordinaria. Use excepciones para notificar y controlar las condiciones de error.
- Las excepciones no se deben devolver como un valor devuelto o un parámetro en lugar de iniciarse.
- No inicie System.Exception, System.SystemException, System.NullReferenceException o System.IndexOutOfRangeException de manera intencional desde su propio código fuente.
- No cree excepciones que se puedan producir en modo de depuración, pero no en modo de versión. Para identificar errores en tiempo de ejecución durante la fase de desarrollo, use Debug Assert en su lugar.
Excepciones en métodos que devuelven tareas
Los métodos declarados con el async
modificador tienen algunas consideraciones especiales cuando se trata de excepciones. Las excepciones iniciadas en un método async
se almacenan en la tarea devuelta y no surgen hasta que, por ejemplo, se espera la tarea. Para obtener más información sobre las excepciones almacenadas, vea Excepciones asincrónicas.
Se recomienda validar los argumentos y lanzar las excepciones correspondientes, como ArgumentException y ArgumentNullException, antes de ingresar en las partes asincrónicas de los métodos. Es decir, estas excepciones de validación deben surgir sincrónicamente antes de que se inicie el trabajo. El siguiente fragmento de código muestra un ejemplo en el que, si se lanzan excepciones, la ArgumentException excepción emergería sincrónicamente, mientras que la InvalidOperationException se almacenaría en la tarea devuelta.
// Non-async, task-returning method.
// Within this method (but outside of the local function),
// any thrown exceptions emerge synchronously.
public static Task<Toast> ToastBreadAsync(int slices, int toastTime)
{
if (slices is < 1 or > 4)
{
throw new ArgumentException(
"You must specify between 1 and 4 slices of bread.",
nameof(slices));
}
if (toastTime < 1)
{
throw new ArgumentException(
"Toast time is too short.", nameof(toastTime));
}
return ToastBreadAsyncCore(slices, toastTime);
// Local async function.
// Within this function, any thrown exceptions are stored in the task.
static async Task<Toast> ToastBreadAsyncCore(int slices, int time)
{
for (int slice = 0; slice < slices; slice++)
{
Console.WriteLine("Putting a slice of bread in the toaster");
}
// Start toasting.
await Task.Delay(time);
if (time > 2_000)
{
throw new InvalidOperationException("The toaster is on fire!");
}
Console.WriteLine("Toast is ready!");
return new Toast();
}
}
Definición de clases de excepción
Los programas pueden lanzar una clase de excepción predefinida en el System espacio de nombres (excepto donde se haya indicado previamente) o crear sus propias clases de excepción derivando de Exception. Las clases derivadas deben definir al menos tres constructores: un constructor sin parámetros, uno que establezca la propiedad de mensaje y otro que establezca tanto la propiedad Message como la propiedad InnerException. Por ejemplo:
[Serializable]
public class InvalidDepartmentException : Exception
{
public InvalidDepartmentException() : base() { }
public InvalidDepartmentException(string message) : base(message) { }
public InvalidDepartmentException(string message, Exception inner) : base(message, inner) { }
}
Agregue nuevas propiedades a la clase de excepción cuando los datos que proporcionan sean útiles para resolver la excepción. Si se agregan nuevas propiedades a la clase de excepción derivada, ToString()
se debe invalidar para devolver la información agregada.
Especificación del lenguaje C#
Para obtener más información, vea Excepciones y la instrucción throw en la especificación del lenguaje C#. La especificación del lenguaje es el origen definitivo de la sintaxis y el uso de C#.