viernes, 11 de julio de 2014

Excepciones en C# - Parte 3: Diseño de Excepciones Personalizadas

Tabla de Contenido

0. Introducción
1. Jerarquía General de Clases de .NET Framework
2. Diseño de Excepciones Personalizadas
2.1 Creación de una excepción personalizada
2.1.1 Excepción LoginFalloException
2.1.2 Aplicaciones
2.1.2.1 Consola
2.1.2.2 WinForms
3. Guías de Diseño de Excepciones
4. Conclusiones
5. Glosario
6. Literatura & Enlaces

0. Introducción

Damos inicio a la tercera parte de la serie de excepciones en C#: en esta ocasión aprenderemos a crear nuestras propias excepciones personalizadas. A pesar de que la biblioteca base de clases de .NET Framework cuenta con un conjunto enriquecido de clases de excepciones, surgirán situaciones en donde como programadores requerimos crear un nivel de granularidad adicional para el lanzamiento y captura de excepciones de acuerdo a la lógica de negocios y el modelo del mundo (o dominio) del problema. Conoceremos las clases de excepciones bases, desde las que podemos crear las nuestras propias y reusar el código definido en las clases de excepciones base.

1. Jerarquía General de Clases de .NET Framework

Microsoft .NET Framework cuenta con un sinnúmero de excepciones en su biblioteca base de clases. Estas excepciones se hayan definidas en una jerarquía que depende el contexto o del tipo de excepción. Se empieza por la clase System.Object; a partir de esta se define la clase base para todas las excepciones: System.Exception [15]. Esta última va a convertirse en la clase base para dos tipos de excepciones:
  • Excepciones de sistema: SystemException [16], y
  • Excepciones de aplicación: ApplicationException [17]

[Nota: De acuerdo [5], se desaconseja el uso de la excepción ApplicationSystem ya que lo único que hace es agregar un nivel más en la jerarquía de herencia de excepciones. En su lugar se recomienda heredar directamente desde System.Excepcion. Esta es la sugerencia original [11]:
«You should not define new exception classes derived from ApplicationException; use Exception instead. In addition, you should not write code that catches ApplicationException.»
]


En la Figura 1 se muestra la jerarquía de herencia de excepciones de sistema.
Jerarquía de Excepciones .NET
Figura 1. Jerarquía de Excepciones .NET.


2. Diseño de Excepciones Personalizadas

Para diseñar una excepción personalizada debemos (deberíamos) realizar el siguiente conjunto de tareas:
  1. Heredar de la clase System.Exception
  2. El nombre de la nueva clase de excepción debe terminar con el sufijo Exception. Ejemplo:

    public class ExcepcionPersonalizadaException : System.Exception
  3. Agregar las siguientes firmas de constructores:

    public ExcepcionPersonalizadaException () {} public ExcepcionPersonalizadaException (string message) {} public ExcepcionPersonalizadaException (string message, Exception innerException) {} public ExcepcionPersonalizadaException (SerializationInfo info, StreamingContext context) {}

    Para este último constructor es necesario añadir el atributo SerializableAttribute [12], para que la excepción pueda usar en distintos dominios aplicación (cfr. Creación de un Dominio de Aplicación [Application Domain]) o desde una locación remota.

    [Serializable]
    public class ExcepcionPersonalizadaException : System.Exception
  4. Seguir las guías de diseño de excepciones recomendadas en la sección 3.

2.1 Creación de una excepción personalizada

Crearemos y usaremos una excepción que se genere cuando un usuario intenta autenticarse en un formulario con su nombre de usuario y contraseña y falle su intento.

2.1.1 Excepción LoginFalloException

Definamos la jerarquía de herencia a partir de la clase System.Exception:

En la línea 6 marcamos la clase LoginFalloException con el atributo [Serializable]. Los miembros de esta clase son cuatro constructores que invocan a los constructores de la clase base System.Exception.

Descripción puntual de cada uno de los constructores de la clase LoginFalloException:
  • LoginFalloException () (líneas 11 y 12): Este constructor inicializa una instancia de la clase LoginFalloException e invoca al constructor de cero-argumentos de Exception.
  • LoginFalloException (string message) (líneas 13 y 14): Inicializa una instancia de LoginFalloException y recibe como argumento un objeto string que corresponde con el mensaje que describe el error al generarse la excepción.
  • LoginFalloException (string message, Exception innnerException) (líneas 16-18): crea una instancia de LoginFalloException. Recibe un objeto string que contiene el mensaje de error de la excepción, y la referencia al tipo de excepción que generó la excepción LoginFalloException.
  • LoginFalloException (SerializationInfo info, StreamingContext context) (líneas 20-22): Crea una instancia de LoginFalloException con información serializada (cfr. Persistencia de Datos de Objeto).
Compilación:

  1. csc /target:library LoginFalloException.cs

2.1.2 Aplicaciones

2.1.2.1 Consola

Creamos una aplicación basada en una consola para demostrar la utilidad de la excepción LoginFalloExcepcion.



E la línea 23 se crea una instancia de LoginFalloException cuando las credenciales no coincidicen (línea 16) con las introducidas por el usuario (línea 12 y 14). Esta excepción es capturada en el bloque catch de las líneas 28-31. El tipo de excepción aquí manipulada corresponde con el tipo de mayor jerarquía: Exception. En la línea 30 se muestra el mensaje asociado con el error de inicio de sesión invocando a la propiedad Message.


Compilación:


  1. csc /target:exe /r:LoginFalloException.dll AplicacionConsola.cs

Ejecución assembly:


  1. .\AplicacionConsola.exe

> Prueba de ejecución:
Ejecución assembly AplicacionConsola.exe
Figura 2. Ejecución assembly AplicacionConsola.exe.
2.1.2.2 Formulario WinForms

Creamos un formulario (usando solo un editor de código de texto [Notepad++]) para probar la excepción LoginFalloException.


Archivo C# AplicacionWinForms.cs [enlace alternativo]:

Compilación:


  1. csc /target:exe AplicacionWinForms.cs

Ejecución assembly:


  1. .\AplicacionWinForms.exe

> Prueba de ejecución:
Ejecución assembly AplicacionWinForms.exe
Figura 3. Ejecución assembly AplicacionWinForms.exe.

3. Guía de Diseño de Excepciones

A partir de la referencia [4] extraigo las siguientes guías de diseño de excepciones:
  • Evite a toda costa la creación de jerarquías de excepciones de gran profundidad.
  • Cree sus propias excepciones a partir de las excepciones de sistema, es decir, desde System.Exception o cualquier otra excepción intermedia.
  • El nombre de la clase de la excepción debe(ría) terminar con el sufijo Exception.
  • Marque las excepciones con el atributo Serializable para permitir que estas funcionen sobre dominios de aplicación o remotamente.
  • Use los constructores mencionados a principio de la sección 2.
  • Tenga cuidado con exponer información sensible (contraseñas de cuentas de usuario, por ejemplo) en los mensajes generados por la excepción. En caso de que requiera hacerlo, exponga una capa de seguridad para proteger estos datos: por ejemplo, a través de permisos.
  • La información sensible debería ser guarda en miembros privados. Esto va a asegurar que sólo el código seguro tenga acceso.

  • Una clase de excepción puede contener campos miembro adicionales para guardar información de su estado.

4. Conclusiones

Hemos explorado las guías de diseño de excepciones. Además, hemos puesto en práctica los conceptos y principios de diseño en la creación de una excepción personalizada en la sección 2. Las aplicaciones demostración están basadas en una consola y un formulario, en las que se demuestra el lanzamiento de la excepción, y su respectivo tratamiento. Las guías de diseño presentadas en la sección 3, son consideraciones importantes a tener en cuenta a la hora de crear excepciones para nuestras aplicaciones. En la siguiente parte exploraremos las propiedades de la clase System.Exception para comprender su utilidad en las excepciones de sistema y las propias creadas por el programador.

5. Glosario

  • CLR
  • Excepción
  • Excepción de aplicación
  • Excepción de sistema
  • Exception
  • Guía de dieño
  • Lanzamiento excepción
  • Tratamiento de una excepción

Literatura & Enlaces

[1]: C# 5.0 in a Nutshell by Joseph Albahari and Ben Albahari. Copyright 2012 Joseph Albahari and Ben Albahari, 978-1-449-32010-2.
[2]: Creating and Throwing Exceptions (C# Programming Guide) - http://msdn.microsoft.com/en-us/library/vstudio/ms173163(v=vs.100).aspx
[3]: Custom Exceptions: When should you create them? - jaredpar's WebLog - Site Home - MSDN Blogs - http://blogs.msdn.com/b/jaredpar/archive/2008/10/20/custom-exceptions-when-should-you-create-them.aspx
[4]: Designing Custom Exceptions - http://msdn.microsoft.com/en-us/library/vstudio/ms229064(v=vs.100).aspx
[5]: Creating Custom Exceptions in .NET - http://blog.gurock.com/articles/creating-custom-exceptions-in-dotnet/
[6]: Custom exceptions in C#.NET - CodeProject - http://www.codeproject.com/Tips/90646/Custom-exceptions-in-C-NET
[7]: Creating custom exceptions (C# Programming Tutorial) • Geekpedia - http://www.geekpedia.com/tutorial80_Creating-custom-exceptions.html
[8]: C# Tutorial: Custom Exceptions - http://csharptutorial.blogspot.com/2006/05/custom-exceptions.html
[9]: Custom Exception Handling in C# - http://www.c-sharpcorner.com/UploadFile/susanabraham/CustomExceptionHandling06022005011154AM/CustomExceptionHandling.aspx
[10]: .NET tutorials: Custom Exceptions - http://www.dotnetspider.com/tutorials/DotNet-Tutorial-288.aspx
[11]: Introducing the .NET Framework Standard Library Annotated Reference Vol1 - Brad Abrams - Site Home - MSDN Blogs - http://blogs.msdn.com/b/brada/archive/2004/03/25/96251.aspx
[12]: SerializableAttribute Class (System) - http://msdn.microsoft.com/en-us/library/system.serializableattribute(v=vs.110).aspx
[13]: Receta No. 3-1 en C#: Creación de un Dominio de Aplicación (Application Domain) | OrtizOLón Software (xCSw) - http://ortizol.blogspot.com/2014/05/receta-no-3-1-en-c-creacion-de-un.html
[14]: Receta No. 2-13 en C#: Persistencia de Datos de Objeto en un Archivo | OrtizOLón Software (xCSw) - http://ortizol.blogspot.com/2014/05/receta-no-2-13-en-c-persistencia-de.html
[15]: Exception Class (System) - http://msdn.microsoft.com/en-us/library/System.Exception(v=vs.110).aspx
[16]: SystemException Class (System) - http://msdn.microsoft.com/En-US/library/system.systemexception(v=vs.110).aspx
[17]: ApplicationException Class (System) - http://msdn.microsoft.com/en-us/library/system.applicationexception(v=vs.110).aspx


J

No hay comentarios:

Publicar un comentario

Envíe sus comentarios, dudas, sugerencias, críticas. Gracias.