Compartir a través de


Crear y producir excepciones (Guía de programación de C#)

Las excepciones se utilizan para indicar que se ha producido un error mientras el programa está en ejecución. Los objetos de excepción que describen un error se crean y, a continuación, se producen con la palabra clave throw. El motor de ejecución busca el controlador de excepciones más compatible.

Los programadores deberían iniciar excepciones cuando se cumpla al menos una de las siguientes condiciones:

  • El método no puede finalizar su funcionalidad definida.

    Por ejemplo, si el parámetro de un método tiene un valor no válido:

    static void CopyObject(SampleClass original)
    {
        if (original == null)
        {
            throw new System.ArgumentException("Parameter cannot be null", "original");
        }
    
    }
    
  • Se realiza una llamada inadecuada a un objeto, basada en el estado del objeto.

    Un ejemplo sería tratar de escribir en un archivo de sólo lectura. En los casos en que el estado del objeto no permite realizar una operación, produzca una instancia de InvalidOperationException o un objeto basado en una derivación de esta clase. Éste es un ejemplo de un método que produce un objeto InvalidOperationException:

    class ProgramLog
    {
        System.IO.FileStream logFile = null;
        void OpenLog(System.IO.FileInfo fileName, System.IO.FileMode mode) {}
    
        void WriteLog()
        {
            if (!this.logFile.CanWrite)
            {
                throw new System.InvalidOperationException("Logfile cannot be read-only");
            }
            // Else write data to the log and return.
        }
    }
    
  • Cuando un argumento para un método provoca una excepción.

    En este caso, se debería detectar una excepción original y se debería crear una instancia de ArgumentException. La excepción original se debería pasar al constructor de ArgumentException como el parámetro InnerException:

    static int GetValueFromArray(int[] array, int index)
    {
        try
        {
            return array[index];
        }
        catch (System.IndexOutOfRangeException ex)
        {
            System.ArgumentException argEx = new System.ArgumentException("Index is out of range", "index", ex);
            throw argEx;
        }
    }
    

Las excepciones contienen una propiedad denominada StackTrace. Esta cadena contiene el nombre de los métodos incluidos en la pila actual de llamadas, junto con el nombre del archivo y el número de línea donde se produjo la excepción para cada método. Common Language Runtime (CRL) crea automáticamente un objeto StackTrace desde el punto de la instrucción throw, de modo que las excepciones se deben iniciar desde el punto donde debe comenzar el seguimiento de la pila.

Todas las excepciones contienen una propiedad denominada Message. Esta cadena debería contener el motivo de la excepción. Tenga en cuenta que no se debe colocar información confidencial de seguridad en el texto del mensaje. Además de Message, ArgumentException contiene una propiedad denominada ParamName cuyo valor debe ser el nombre del argumento que provocó que se iniciara la excepción. En el caso de un establecedor de propiedades, ParamName se debería establecer en value.

Los miembros de métodos públicos y protegidos deberían producir excepciones cada vez que no pueden finalizar sus funciones deseadas. La clase de excepción producida debería ser la excepción más concreta disponible que se ajuste a las condiciones del error. Estas excepciones se deberían documentar como parte de la funcionalidad de la clase, y las clases derivadas o actualizaciones de la clase original deberían mantener el mismo comportamiento a efectos de compatibilidad con versiones anteriores. Para obtener más información, vea Instrucciones de diseño de excepciones.

Cosas que hay que evitar al producir excepciones

La siguiente lista identifica las prácticas que hay que evitar a la hora de producir excepciones:

  • Las excepciones no se deberían utilizar para cambiar el flujo de un programa en una ejecución normal. Las excepciones sólo se deberían utilizar para comunicar y tratar errores.

  • Las excepciones no se deben devolver como un valor o parámetro en lugar de iniciarse.

  • No inicie intencionadamente System.Exception, System.SystemException, System.NullReferenceException o System.IndexOutOfRangeException desde el propio código fuente.

  • No cree excepciones que se pueden iniciar en modo de depuración pero no en modo de versión de lanzamiento. Para identificar errores en tiempo de ejecución durante la fase de desarrollo, use en su lugar el método Debug Assert.

Definir clases de excepción

Los programas pueden iniciar una clase de excepción predefinida en el espacio de nombres System (excepto donde se indicó anteriormente) o crear sus propias clases de excepción mediante derivación de Exception. Las clases derivadas deberían definir al menos cuatro constructores: un constructor predeterminado, uno que establezca la propiedad message y otro que establezca las propiedades Message y InnerException. El cuarto constructor se utiliza para serializar la excepción. Las nuevas clases de excepción deberían ser serializables. Por ejemplo:

[Serializable()]
public class InvalidDepartmentException : System.Exception
{
    public InvalidDepartmentException() : base() { }
    public InvalidDepartmentException(string message) : base(message) { }
    public InvalidDepartmentException(string message, System.Exception inner) : base(message, inner) { }

    // A constructor is needed for serialization when an
    // exception propagates from a remoting server to the client. 
    protected InvalidDepartmentException(System.Runtime.Serialization.SerializationInfo info,
        System.Runtime.Serialization.StreamingContext context) { }
}

Las nuevas propiedades sólo se deberían agregar a la clase de excepción cuando los datos que proporcionan son útiles para resolver la excepción. Si a la clase de excepción derivada se agregan nuevas propiedades, ToString() se debería reemplazar para devolver la información agregada.

Especificación del lenguaje C#

Para obtener más información, vea 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#)

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

Conceptos

Guía de programación de C#

Jerarquía de excepciones