Generación de excepciones
Las excepciones se inician cuando un miembro no puede hacer correctamente lo que está diseñado para hacer. Este hecho se conoce como error de ejecución. Por ejemplo, si el método Connect no puede conectar con el punto final remoto especificado, se trata de un error de ejecución y se inicia una excepción.
Las instrucciones siguientes ayudan a garantizar que se inician excepciones cuando corresponde.
No devuelva códigos de error. Las excepciones son los principales medios de informar de errores producidos en marcos de trabajo.
Instrucciones de diseño de excepciones explica muchas de las ventajas que aporta el uso de excepciones.
Informe de los errores de ejecución iniciando excepciones. Si un miembro no puede hacer correctamente lo que está diseñado para hacer, se considera como un error de ejecución y se debe iniciar una excepción.
Considere la posibilidad de finalizar el proceso llamando a System.Environment.FailFast(System.String) (una característica de la versión 2.0 de .NET Framework) en lugar de iniciar una excepción si su código encuentra una situación en la que no es seguro continuar con la ejecución.
Si es posible, no utilice excepciones para el control normal del flujo. Excepto en el caso de errores del sistema y operaciones con posibles condiciones de carrera, los diseñadores de marcos de trabajo deberían diseñar las API de manera que los usuarios puedan escribir código que no inicie excepciones. Por ejemplo, puede proporcionar una manera de comprobar las condiciones previas antes de llamar a un miembro para que los usuarios puedan escribir código que no inicie excepciones.
El ejemplo de código siguiente muestra las comprobaciones necesarias para evitar que se inicien excepciones cuando una cadena de mensaje es null (Nothing en Visual Basic).
Public Class Doer
' Method that can potential throw exceptions often.
Public Shared Sub ProcessMessage(ByVal message As String)
If (message = Nothing) Then
Throw New ArgumentNullException("message")
End If
End Sub
' Other methods...
End Class
Public Class Tester
Public Shared Sub TesterDoer(ByVal messages As ICollection(Of String))
For Each message As String In messages
' Test to ensure that the call
' won't cause the exception.
If (Not (message) Is Nothing) Then
Doer.ProcessMessage(message)
End If
Next
End Sub
End Class
public class Doer
{
// Method that can potential throw exceptions often.
public static void ProcessMessage(string message)
{
if (message == null)
{
throw new ArgumentNullException("message");
}
}
// Other methods...
}
public class Tester
{
public static void TesterDoer(ICollection<string> messages)
{
foreach (string message in messages)
{
// Test to ensure that the call
// won't cause the exception.
if (message != null)
{
Doer.ProcessMessage(message);
}
}
}
}
public ref class Doer
{
public:
// Method that can potential throw exceptions often.
static void ProcessMessage(String^ message)
{
if (message == nullptr)
{
throw gcnew ArgumentNullException("message");
}
}
// Other methods...
};
public ref class Tester
{
public:
static void TesterDoer(ICollection<String^>^ messages)
{
for each (String^ message in messages)
{
// Test to ensure that the call
// won't cause the exception.
if (message != nullptr)
{
Doer::ProcessMessage(message);
}
}
}
};
Para obtener información adicional sobre modelos de diseño que pueden reducir el número de excepciones iniciadas, vea Excepciones y rendimiento.
Considere las implicaciones de rendimiento de iniciar las excepciones.
Documente todas las excepciones iniciadas por miembros invocables públicamente a causa de una infracción del contrato de miembros (en lugar de por un error del sistema) y trátelas como parte del contrato. Las excepciones que forman una parte del contrato no deberían cambiar de una versión a la siguiente.
No incluya miembros públicos que puedan iniciar o no excepciones basadas en función de alguna opción.
Por ejemplo, no defina los miembros como sigue:
Private Function ParseUri(ByVal uriValue As String, ByVal throwOnError As Boolean) As Uri
Uri ParseUri(string uriValue, bool throwOnError)
Uri^ ParseUri(String^ uriValue, bool throwOnError)
No incluya miembros públicos que devuelvan excepciones como valores devueltos o como un parámetro de salida.
Esta instrucción es para los miembros públicamente visibles. Es aceptable utilizar un método auxiliar privado para construir e inicializar las excepciones.
Considere la posibilidad de utilizar métodos de generador de excepciones. Es frecuente iniciar la misma excepción desde distintos lugares. Para evitar que el código se haga demasiado grande, utilice métodos auxiliares para crear excepciones e inicializar sus propiedades.
El método auxiliar no debe iniciar la excepción o el seguimiento de la pila no reflejará con precisión la pila de llamadas que produjo la excepción.
No inicie excepciones desde bloques de filtro de excepciones. Cuando un filtro de excepciones provoca una excepción, Common Language Runtime (CLR) la detecta y el filtro devuelve false. Este comportamiento es indistinguible desde que el filtro se ejecuta y devuelve false explícitamente, y por consiguiente es muy difícil depurar.
Algunos lenguajes como C# no admiten los filtros de excepciones.
Evite iniciar explícitamente excepciones desde bloques finally. Son aceptables las excepciones iniciadas implícitamente que son resultado de llamar a los métodos que las inician.
Portions Copyright 2005 Microsoft Corporation. Reservados todos los derechos.
Portions Copyright Addison-Wesley Corporation. Reservados todos los derechos.
Para obtener más información sobre las directrices de diseño, consulte “las instrucciones de diseño de Framework: Convenciones, frases realizadas y modelos para libro de bibliotecas reutilizables de .NET” de Krzysztof Cwalina y Brad Abrams, publicados por Addison-Wesley, 2005.
Vea también
Conceptos
Elegir el tipo correcto de la excepción que se va a producir
Otros recursos
Instrucciones de diseño para desarrollar bibliotecas de clases