¿Cuándo se supone que se debe usar "Try" en los nombres de métodos de C #?

180

Estábamos discutiendo con nuestros compañeros de trabajo sobre lo que significa si el nombre del método comienza con "Probar".

Hubo las siguientes opiniones:

  • Use "Probar" cuando el método pueda devolver un valor nulo.
  • Use "Probar" cuando el método no arroje una excepción.

¿Cuál es la definición oficial? ¿Qué dice "Probar" en el nombre del método? ¿Hay alguna directriz oficial sobre esto?

ms007
fuente
83
+1 Las personas que piensan tanto en los nombres de sus funciones en realidad están buscando al "próximo tipo". No estoy seguro de por qué esto está obteniendo votos cercanos (y eso proviene de un tipo que ha emitido muchos de ellos esta noche).
Jonathon Reinhart
77
@JonathonReinhart, obtuvo votos cercanos porque "tal como está actualmente, esta pregunta no se ajusta bien a nuestro formato de preguntas y respuestas. Esperamos que las respuestas estén respaldadas por hechos, referencias o experiencia específica, pero esta pregunta probablemente requerirá debate, argumentos , votación o discusión extendida ".
Pranav Hosangadi
16
No es una declaración oficial de Microsoft que responde a la pregunta (véase mi respuesta). ¿Cómo es que eso no es un hecho?
Erik Schierboom
66
@PranavHosangadi, como Erik mencionó, está respaldado por hechos. Además, aquí hay muchos desarrolladores de C # muy experimentados que tienen experiencia específica para proporcionar una respuesta válida. Demonios, Eric Lippert es el arquitecto jefe de lenguaje C #. Creo que se puede llamar a esa experiencia específica .
Jonathon Reinhart
44
@ErikSchierboom Que es la directriz de MS es un hecho. Que la directriz MS es la directriz correcta para usar es subjetiva y discutible.
Servy

Respuestas:

148

Esto se conoce como el patrón TryParse y ha sido documentado por Microsoft. La página oficial de Excepciones y rendimiento de MSDN dice :

Considere el patrón TryParse para los miembros que pueden lanzar excepciones en escenarios comunes para evitar problemas de rendimiento relacionados con las excepciones.

Por lo tanto, si tiene un código para el que un caso de uso regular significaría que podría arrojar una excepción (como analizar un int), el patrón TryParse tiene sentido.

Erik Schierboom
fuente
2
Otro enlace útil que documenta este patrón (busque TryParse) blogs.msdn.com/b/kcwalina/archive/2005/03/16/396787.aspx
Vivek Maharajh
2
Básicamente, si tiene un método TryParse, debe tener un método Parse que arroje cuando TryParse devuelva falso. Por el contrario, si tiene un método Parse, debería considerar tener un método TryParse que devuelva falso cuando Parse arrojaría
3Doubloons
55
+1. Solo para agregar a esto, las excepciones son generalmente para circunstancias "excepcionales". Si está haciendo algo que podría fallar fácilmente y ese fracaso no es particularmente notable, entonces usar este patrón es más idiomático que un intento / captura
Adam Robinson
¿Tal patrón realmente requería pautas de Microsoft? Parece algo bastante básico.
Dave Lawrence
19
Que es lo básico, pero eso no significa que las directrices no son útiles. Hacer las cosas básicas correctamente puede ser bastante difícil si no conoce la plataforma lo suficientemente bien.
Erik Schierboom
119

(Corregido) Existe una directriz oficial, como sugirió Erik.

Cuando veo el TrySomethingmétodo, lo asumo

  • no tira
  • devoluciones bool
  • si espero valor, se devuelve a través del parámetro 'out'
  • Existe un Somethingmétodo que me permite manejar cualquier excepción yo mismo. (editar, sugerido por Jesse Webb)
nada
fuente
44
Corrección: tiene una directriz oficial. Ver la respuesta de Erik.
nothrow
8
+1 Pero también tengo una cuarta expectativa: si hay un TryFoométodo, habrá un Foométodo similar que me permita manejar cualquier `` excepción yo mismo. Las firmas de estos métodos probablemente serán diferentes, por lo que sus usos no son intercambiables sin otros cambios de código.
Jesse Webb
1
@JesseWebb, gracias por señalarlo. Agregué tu comentario a mi respuesta, si no te importa.
nothrow
1
"No arroja" me parece demasiado generalizado. Por ejemplo, Int32. TryParse (String, NumberStyles, IFormatProvider, Int32) lanza ArgumentException si no le gusta el parámetro de estilo.
Jirka Hanika
Estoy de acuerdo en que "no arroja" podría considerarse sobregeneralizado, pero creo que la intención era transmitir que no arroja como resultado de la ejecución y no como resultado del valor de los parámetros.
ConfusingBoat
8

Creo que deberías usar trycuando quieras continuar. No importa que un método devuelva algún valor o no.

Caso 1: si vuelve bien, puede proceder de alguna manera.

Caso 2: si no regresa: todavía está bien; puedes proceder de otra manera.

Y si espera algún valor como resultado de ese método, use el outparámetro.

Ejemplo

int value
if (dictionary.TryGetValue("key", out value))
{
    // Proceed in some way
}
else
{
    // Proceed in some other way
}
Ashok Damani
fuente
6

Debe usar "Probar" en el nombre del método, cuando desee manifestar el hecho de que la invocación del método puede producir un resultado no válido. Siguiendo el estándar .NET, por cierto, no es una función que genera una excepción, sino la función que devuelve algo VALIDo NON_VALID, desde la perspectiva del programa, valor.

Al final, se trata de una convención de nomenclatura que decides usar en tu grupo.

Tigran
fuente
5

Asegúrese de incluir tryen su nombre de método si:

  • no lanzas ninguna excepción
  • su método tiene la siguiente firma: bool TrySomething(input, out yourReturn)

Básicamente, si usamos try-methods solo obtenemos un resultado booleano.

Entonces, el siguiente código no arrojará ninguna excepción:

string input = "blabla";
int number;
if (int.TryParse(input, out number))
{
// wooohooo we got an int!
} else
{
//dooh!
}

Mientras que este código puede (y en este caso lo hará) lanzar excepciones:

string input = "blabla";
int number;
try
{
     number = int.Parse(input); //throws an exception
}
catch (Exception)
{
     //dooh!
}

Usar métodos Try es una forma más segura y más defensiva de codificar. Además, el fragmento de código # 2 requiere más rendimiento para ejecutarse si no es un número entero.

Fabian Bigler
fuente
Su fragmento de código n. ° 2 debería leer int number = int.Parse(input);si desea que sea más significativo en este contexto.
Pierre Arnaud
@PierreArnaud Gracias, ¡lo cambié!
Fabian Bigler
Todavía falta la int number;declaración antes del bloque try y la number = ...asignación.
Pierre Arnaud
@PierreArnaud Gracias, también incluí 'int number' ahora.
Fabian Bigler
Tenga en cuenta que aún puede lanzar excepciones si la excepción no está relacionada con la acción directa que se realiza, como TryLoadFile(path, out file)woah, fuera de la RAM. Por lo tanto, la persona que llama no esperaría errores por una ruta incorrecta o acceso denegado, sino una excepción por las cosas más complicadas que también podrían salir mal. Y documentarlo.
Luke Puplett
0

El tío Bob da el siguiente ejemplo en su libro Clean Code . Siempre que esperemos que se produzca una excepción, podemos usar el Tryprefijo del nombre de un método:

public void sendShutDown()
{
    try{
        tryToShutDown();
    } catch (DeviceShutDownError e) {
        logger.log(e);            
    }
}

Y luego (adaptado):

private void tryToShutDown()
{
    //some code with no error handling, but
    //something might go wrong here
}

El tryToShutDownmétodo no realiza ningún manejo de errores, porque es responsabilidad del sendShutDownmétodo.

los TryParse patrón de Microsoft viola la directriz de código limpio que dice que debemos evitar los parámetros de salida.

Si no estamos desarrollando una nueva versión de C #, no tenemos que cumplir con todas las pautas de Microsoft. A veces no son los mejores.

Glauber
fuente