Una excepción definida por el usuario es cualquier clase definida en tu código que derive de System.Exception. Está sujeta a todas las reglas de la herencia de clases, pero además el compilador y el entorno de ejecución del lenguaje tratan esas clases de forma especial, lo que permite lanzar y capturar sus instancias fuera del flujo de control normal, como se explica en el ejercicio exceptions. Las excepciones definidas por el usuario se pueden usar de todas las formas en que se usan las excepciones del entorno de ejecución y de la Microsoft Base Class Library.
Este trato especial se aplica solo a las clases derivadas de Exception. No puedes lanzar instancias de ningún otro tipo.
Las excepciones definidas por el usuario se usan a menudo para llevar información adicional, como un mensaje y otros datos relevantes, que esté disponible para las rutinas que capturan la excepción. Esa información se puede registrar en los registros, informarse al usuario o quizás usarse en una operación de reintento. System.Exception tiene miembros de datos convenientes y constructores adecuados para guardar un mensaje y la excepción «interna».
Por convención, los nombres de las clases de excepción terminan en «Exception», por ejemplo MyTerribleException.
Aunque usar excepciones definidas por el usuario para envolver y mejorar excepciones de terceros es un patrón que se ve con frecuencia, el consejo general es no usarlas de forma demasiado liberal en tu propio código fuera de ese caso. Se considera un antipatrón. Hay quienes cuestionan esta opinión, y puedes ver ambos lados del argumento en esta publicación de Stack Exchange.
Este artículo es una buena introducción a las excepciones definidas por el usuario.
Como parte de su guía sobre crear y lanzar excepciones, el equipo de .NET recomienda que las excepciones definidas por el usuario tengan varios constructores de conveniencia. Para la mayoría de los propósitos, la combinación que se ilustra a continuación es la adecuada.
public class IncompleteExerciseException : System.Exception
{
public IncompleteExerciseException() : base() { }
public IncompleteExerciseException(string message) : base(message) { }
public IncompleteExerciseException(string message, System.Exception inner) : base(message, inner) { }
}