¿Debo derivar excepciones personalizadas de Exception o ApplicationException en .NET?

¿Cuál es la mejor práctica al crear sus clases de excepción en una solución .NET: derivar de System.Exception o de System.ApplicationException ?

De acuerdo con Jeffery Richter en el libro de pautas de diseño del marco:

System.ApplicationException es una clase que no debe ser parte del framework .NET.

Tenía la intención de tener algún significado porque potencialmente podría atrapar “todas” las excepciones de la aplicación, pero no se siguió el patrón, por lo que no tiene ningún valor.

Debe derivar excepciones personalizadas de System.Exception .

Incluso MSDN ahora dice que ignore ApplicationException :

Si está diseñando una aplicación que necesita crear sus propias excepciones, se le recomienda derivar excepciones personalizadas de la clase Excepción. Originalmente se pensó que las excepciones personalizadas deberían derivar de la clase ApplicationException; sin embargo, en la práctica esto no se ha encontrado para agregar un valor significativo. Para obtener más información, vea las Mejores prácticas para manejar excepciones .

http://msdn.microsoft.com/en-us/library/system.applicationexception.aspx

ApplicationException considerada inútil es un argumento fuerte y crítico contra ApplicationException .

Upshot: no lo use. Derivar de la Exception .

Los autores del marco consideran que ApplicationException no tiene valor:

http://blogs.msdn.com/kcwalina/archive/2006/06/23/644822.aspx

con un buen seguimiento aquí:

http://blogs.msdn.com/kcwalina/archive/2006/07/05/657268.aspx

En caso de duda, sigo las Pautas de diseño del marco de su libro.

http://www.amazon.com/Framework-Design-Guidelines-Conventions-Development/dp/0321246756

El tema de la publicación del blog se analiza con más detalle allí.

rp

Estoy acostumbrado a hacer:

 private void buttonFoo_Click() { try { foo(); } catch(ApplicationException ex) { Log.UserWarning(ex); MessageVox.Show(ex.Message); } catch(Exception ex) { Log.CodeError(ex); MessageBox.Show("Internal error."); } } 

Permite hacer la diferencia entre:

  • Error del sistema de código C # que debo reparar.
  • Error de usuario “normal” que no necesita corrección de mi parte.

Sé que no se recomienda usar ApplicationException, pero funciona muy bien ya que hay muy pocas clases que no respetan el patrón ApplicationException.