Como esta pregunta está etiquetada como "C#", podemos consultar las Pautas de diseño de .NET Framework como un buen punto de partida para responder este tipo de preguntas. Esta es la guía dada en MSDN bajo "Exception Throwing":
No use excepciones para un flujo de control normal, si es posible. Excepto para fallas del sistema y operaciones con posibles condiciones de carrera, los diseñadores del framework deben diseñar API para que los usuarios puedan escribir el código que no arroje excepciones. Por ejemplo, puede proporcionar una forma de verificar las condiciones previas al antes de llamar a un miembro para que los usuarios puedan escribir el código que no arroje excepciones.
Aquí se muestra un ejemplo de un mal práctica donde se manipula una excepción, pero casi siempre puede evitarse:
public int? GetItem(int index)
{
int? value = null;
try
{
value = this.array[index];
}
catch (IndexOutOfRangeException)
{
}
return value;
}
Esto parece ideado pero veo código como este muy a menudo a partir de nuevos programadores. Suponiendo una sincronización adecuada alrededor de las lecturas y escrituras en array
, esta excepción se puede evitar de manera determinista al 100%. Teniendo en cuenta que, una mejor manera de escribir ese código sería el siguiente:
public int? GetItem(int index)
{
int? value = null;
// Ensure the index is within range in the first place!
if (index >= 0 && index < this.array.Length)
{
value = this.array[index];
}
return value;
}
Hay otros casos en los que no se puede evitar de una manera excepciones y sólo hay que manejarlos. Esto se presenta con mayor frecuencia cuando tiene que tratar con recursos externos, como archivos o conexiones de red, a los que podría perder acceso o contactar en cualquier momento. Ejemplo de WCF:
public void Close()
{
// Attempt to avoid exception by doing initial state check
if (this.channel.State == CommunicationState.Opened)
{
try
{
// Now we must do a (potentially) remote call;
// this could always throw.
this.channel.Close();
}
catch (CommunicationException)
{
}
catch (TimeoutException)
{
}
}
// If Close failed, we might need to do final cleanup here.
if (this.channel.State == CommunicationState.Faulted)
{
// local cleanup -- never throws (aside from catastrophic situations)
this.channel.Abort();
}
}
Incluso en el ejemplo anterior, es bueno comprobar que la operación que se va a hacer por lo menos tiene la oportunidad de éxito. Entonces todavía hay una verificación if()
, seguida por la lógica de manejo de excepciones apropiada.
'El entrevistador parecía estar esperando alguna otra respuesta' - entonces ¿por qué no le preguntas? Siempre estoy más impresionado por una pregunta que por una respuesta al entrevistar ... –