2010-03-24 13 views
11

Sé que siempre debe verificar params entrantes a un método para null. Pero, ¿qué sucede si tengo este escenario con un try/catch que hace referencia a una variable local? ¿Realmente necesito verificar null a continuación? Debido a que va a la captura de todos modos si es nula y la siguiente línea de código intenta utilizar la variable refundResponse:Si se comprueba nulo

public string DoRefund(...) 
    { 
     try 
     { 
    ...... 
      string refundTransactionID = string.Empty; 
    ...... 

      RefundTransactionResponseType refundResponse = transaction.DoRefund(...); 

      if (refundResponse != null) 
       refundTransactionID = refundResponse.RefundTransactionID; 
    ..... 
     } 
     catch (Exception ex) 
     { 
      LogError(ex); 
      return ex.ToString(); 
     } 
    } 

Recuerda que estoy hablando específicamente de las variables locales y la comprobación de los dentro de un método, no params entrantes a una método.

Todo lo que estoy preguntando es si necesito comprobar null antes de configurar refundTransactionID o simplemente lo configuro sin el si suponiendo que el compilador manejará y arrojará si es nulo que será capturado y devuelto como una cadena para la persona que llama en este caso.

o debe ser

if (refundResponse == null) 
       return null; 

o simplemente tomar el cheque completo para esta asignación variable local y, a continuación, ya que en este caso tengo un try/catch estoy manejando cualquier excepción recogido por el compilador de forma natural mediante la devolución de la excepción como una cadena a la persona que llama (no fue mi decisión de enviar de regreso una cadena, que era un requisito de mi jefe ... por lo que el debate de derivación por ahora):

refundTransactionID = refundResponse.RefundTransactionID; 

en última instancia, la el resto del código más abajo en el método depende de n un reembolso válidoTransactionID.

+11

Coger todas las excepciones y devolver la respuesta como una cadena me parece una práctica de programación muy extraña y probablemente no muy buena en general. Hay algunos casos en los que desea detectar todos los errores, los despachadores de servicios web vienen a la mente, pero la lógica empresarial como esta no parece ser el lugar. –

+0

este es un método de servicio web .. – PositiveGuy

+0

Devolver la cadena depende de cómo se utilizará el servicio web. ¿Cómo puedes decir que no devuelves el error como una cadena? ¿Qué devolverías entonces? No veo nada útil para devolver que no sea el mensaje de error. – PositiveGuy

Respuesta

12

Las excepciones son por condiciones excepcionales. Si puede verificar si hay un error continuo, ¡hágalo, por favor!

+0

sí, pero el compilador ya arrojará una excepción nula si intento usar refundResponse si por algún motivo alguna vez es nulo. Entonces, ¿por qué lanzar una excepción en este caso cuando el compilador lo hará de todos modos y el mensaje de excepción del compilador es lo suficientemente bueno? Eso es lo que estoy debatiendo ... tal vez estoy equivocado, pero así es como se reduciría si fuera nulo y no tuviera ese control allí ... el try/catch lo captaría. – PositiveGuy

+0

Simplemente estoy buscando nulo antes de establecer el ID de transacción. De eso estoy preguntando específicamente. ¿De verdad necesito hacer esto para una variable local o dejo que el compilador genere una excepción de forma natural cuando alcanza la línea que intenta establecer esa transactionID. – PositiveGuy

+0

lo que se considera una condición excepcional, nulo? – PositiveGuy

1

No, no es necesario que compruebe nulo, allí. Sin embargo, eso abre otra pregunta, ¿realmente necesita verificar los parámetros entrantes?

Recuerda: eso es un comportamiento. Tienes que probar ese comportamiento.

0

Sugiero comprobar el nulo y luego hacer algún tipo de manejo de error suave en lugar de simplemente dejarlo atrapar y lanzar un mensaje de error.

+0

bien en este caso el manejo de errores se realiza en el extremo llamante ... ya que este es un método de servicio web que será consumido por mi jefe para su administrador sistema yt es lo que se me dijo que hiciera, devolver una cadena. Sí, creo que es estúpido. – PositiveGuy

1

Pero si no puede continuar en ese punto, deje que la excepción se propague.

8

Sé que siempre debe verificar parámetros entrantes a un método para null.

No, no necesariamente. Lo que debe especificar es el contrato de su método. Es perfectamente aceptable (y común) especificar que arrojará una NullPointer/NullReferenceException para un parámetro null. Entonces no necesitas ninguna verificación.

También puede verificar la nulidad, pero esto solo tiene sentido si realmente puede manejar un nulo de manera útil (por ejemplo, sustituir un valor predeterminado).

+9

Sin embargo, es convencional en .NET arrojar 'ArgumentNullException' cuando un argumento que no se supone' null' recibe un valor 'null'. –

+3

@sleske: Por lo general, es mejor lanzar una 'ArgumentNullException' al comienzo de su método con información sobre el parámetro que es nulo. Si simplemente ignoras la entrada incorrecta y permites que tu código arroje una 'NullReferenceException' en algún momento posterior, es posible que ya hayas realizado varias llamadas internas antes de que eso suceda. En ese momento, la excepción podría provenir de alguna función interna no documentada y el nombre del parámetro podría ser diferente del nombre visible externamente y, por lo tanto, no tendría sentido inmediato para la persona que llama. –

+0

Pavel, esto no es un argumento. Es una variable local dentro de un método. – PositiveGuy

2

Debería tener que comprobar nulo en esa instancia. La lógica de su aplicación debe ser capaz de manejar este tipo de situaciones, sin la necesidad de excepciones.

+0

así lo estoy manejando en este caso en sentido ascendente. Cualquier excepción que ocurra en ese intento, se devolverá a la persona que llama, en este caso se trata de un método de servicio web y mi jefe quería por algún motivo devolver solo una cadena que dijera "éxito" o "error" que para mí es mala. práctica. Es como devolver una respuesta verdadera/falsa que simplemente está mal cuando se lleva a cabo una transacción. – PositiveGuy

1

No, no parece que deba verificar nulo aquí. Y tampoco verificaría nulo para TODOS los parámetros entrantes (como sugiere su descripción).

También es extraño que esté devolviendo un transactionID como una cadena O el mensaje de una excepción. ¿Cómo sabrá la persona que llama de este método si ocurrió una excepción?

Si realmente desea registrar la excepción, ¿qué tal algo como esto:

public string DoRefund(...) 
    { 
     try 
     { 
      return transaction.DoRefund(...).RefundTransactionID; 
     } 
     catch (Exception ex) 
     { 
      LogError(ex); 
      throw ex; 
     } 
    } 
+3

Creo que esto borraría este rastro de pila. Pero tal vez haciendo un LogError (ex); tiro; Eso continuaría la excepción en la pila. – galford13x

+0

bueno, mi jefe es el único que llama y sus requisitos eran que todos estos métodos de servicio web en mi servicio web devuelvan "éxito" o "error". Entonces, en este caso, podría verificar "Aprobado" y, si no se aprueba, recibirá un mensaje de error. – PositiveGuy

+0

Bueno, no estoy lanzando mi trampa ... sí, estarías en lo cierto, pero estoy devolviendo la excepción atrapada (si dijéramos que la variable de respuesta era nula) como una cadena de vuelta a la persona que llama ... de nuevo, esta era una requisito para devolverlo como una cadena. – PositiveGuy

2

Una alternativa a las pruebas es la Null Object pattern. En lugar de devolver Null, o una transacción válida, el método transaction :: DoRefund() devuelve un objeto nulo: un objeto que ofrece la misma interfaz que las instancias RefundTransactionResponseType, pero sus métodos no hacen nada. Con esto no hay necesidad de probar si para Null.

El debe ser utilizado con prudencia ya que esto puede ocultar fácilmente los problemas.

+0

ah, un amigo mío sugirió esto también. Bonito. Pero, ¿y si tu jefe dice que no? no puedes usar ese patrón ;) – PositiveGuy

+0

Tenga en cuenta que este método de servicio web se llamará desde otro idioma que no sea .NET también ... no es que marque la diferencia en su respuesta a mi problema. – PositiveGuy

1

Debe verificar el nulo en lugar de dejar que el manejo de excepciones lo maneje. Como dijo Leppie, las excepciones son para condiciones excepcionales y no para un flujo de control normal. Si sabes qué problemas pueden ocurrir, entonces debes manejarlos con elegancia.

Otra cosa a tener en cuenta es el impacto en el rendimiento de las excepciones. Cuando se lanza la excepción, la JVM tiene que desenrollar la pila de llamadas. En su ejemplo, la excepción también se registra. Todo esto lleva tiempo y es mucho más lento que un simple control "si".

0

Depende de lo que signifique para su programa cuándo (refundResponse == null). Si esto tiene algún significado, entonces tiene sentido informar un error más informativo. Si nunca debería ocurrir e indicaría un error en el método DoRefund, entonces creo que está bien permitir que el nulo cause una excepción más adelante. En el último caso, solo tendría un control específico si sospecha del método y si se está comportando como debería.

Cuestiones relacionadas