2011-02-09 14 views

Respuesta

82

Mejor es altamente subjetiva. Por ejemplo, personalmente prefiero int.TryParse, ya que a menudo no me importa por qué falla, si falla. Sin embargo, int.Parse lata (de acuerdo con el documentation) throw tres excepciones diferentes:

  • la entrada es nulo
  • la entrada no está en un formato válido
  • la entrada contiene un número que procudes un desbordamiento

Si te importa por qué falla, entonces int.Parse es claramente la mejor opción.

Como siempre, el contexto es el rey.

+1

Aunque estoy de acuerdo con el impulso general de que el contexto es el rey, diría que TryParse es * casi siempre * mejor, es un poco más que una preferencia personal muy subjetiva. Su contraejemplo (que distingue las diferentes excepciones que se pueden arrojar) es bastante inusual, y probablemente estaría mejor codificado con un bloque catch para cada tipo de excepción en lugar de catch all. – Joe

+1

@Joe: sí, si desea distinguir entre los diferentes tipos de excepción, cualquier cosa que no sean bloques de captura específicos parecerá muy extraño. Mi respuesta apuntaba a discutir 'Parse' vs' TryParse' en lugar de las muestras de código específico en la pregunta. Como mencioné en otros comentarios, estoy de acuerdo en que 'TryParse' es * casi siempre * la mejor manera de hacerlo, pero la palabra clave es" casi ", no" siempre ". –

+0

@Joe: Ya hice esa discusión. Ver el intercambio de comentarios a la pregunta original. Fredrik tiene razón sobre declaraciones absolutas que nunca son ciertas. (OMG una paradoja!) –

10

El primero. El segundo se considera codificación por excepción.

8

Personalmente, preferiría:

if (int.TryParse(string, out num)) 
{ 
    ... 
} 
4

el primero! No debe codificar por excepción.

usted podría acortarlo a

if (int.TryParse(string, out num))

3

En primer lugar, por el momento. Como dijo George, el segundo es codificar por excepción y tiene un gran impacto en el rendimiento. Y el rendimiento debería ser una preocupación, siempre.

2

Coger una excepción tiene más sobrecarga, así que iré por TryParse.

Además, el método TryParse no arroja una excepción si la conversión falla. Elimina la necesidad de utilizar el manejo de excepciones para probar una FormatException en el caso de que s no sea válida y no pueda ser analizada con éxito.

Esa última parte de la copia pegada-here

37

¿Es excepcional para la conversión a fallar a veces, o es espera y normal que la conversión a veces fallará? Si es el primero, use una excepción . Si el último, evita las excepciones. Las excepciones se llaman "excepciones" por una razón; solo debe usarlos para manejar circunstancias excepcionales.

+1

Me gusta esta explicación porque analizo una gran cantidad de datos de usuario, y si la falla se espera o no (y qué hacer cuando sucede) da forma a todo el proyecto. – JYelton

+0

Eric, me gustaría escuchar sus opiniones en http://www.boost.org/community/error_handling.html: "' ¿Es esta una situación excepcional (o inesperada)? '' Esta guía tiene un atractivo anillo a ella, pero generalmente es un error ... Una pregunta más apropiada para hacer es: '' ¿queremos que la pila se desenrolle aquí? '' " – Jon

+0

@Jon: Varias cosas vienen a la mente. Primero, que no se puede discutir con la tautología de que las excepciones son correctas en aquellas situaciones en las que se desea el comportamiento de una excepción, pero tampoco se puede aprender nada de ella. Segundo, que "excepcional" e "inesperado" son dos cosas diferentes. Y tercero, ¿quién dice que deshacerse de la pila tiene algo que ver con eso? Es un detalle de implementación de C#. Las excepciones arrojadas en los métodos asíncronos no desenrollan la pila; la pila se fue hace mucho tiempo. Señalan una tarea que ocurrió un evento excepcional. No confundas la semántica con la implementación. –

1

Otra cosa a tener en cuenta es que las excepciones se registran (opcionalmente) en la ventana de depuración/salida de Visual Studio. Incluso cuando la sobrecarga de rendimiento de las excepciones puede ser insignificante, escribir una línea de texto para cada excepción cuando la depuración puede ralentizar las cosas.Más excepciones dignas de mención podrían ser ahogadas entre todo el ruido de las operaciones de análisis de enteros fallidos, también.

15

si es de hecho espera que la conversión a veces fallará, me gusta usar int.TryParse y tal ordenadamente en una línea con la conditional (Ternary) operator, así:

int myInt = int.TryParse(myString, out myInt) ? myInt : 0; 

En este caso cero se utilizará como una valor predeterminado si el método TryParse falla.

También es muy útil para los tipos que aceptan nulos, que sobrescribirá cualquier valor predeterminado con null si la conversión falla.

+0

Esto es exactamente equivalente a: 'int myInt; int.TryParse (myString, out myInt); '. TryParse() ya establece el resultado en 0 cuando falla. –

+3

Correcto, pero con mi versión puede especificar un valor predeterminado * alternativo *, como '10'. – greg84