2010-10-03 26 views
24

¿Puede darme un ejemplo de implementación del patrón .NET 'try'?Ejemplo de implementación de 'TryParse' o 'TryGetValue'

Editar:

no me refiero a una declaración "try-catch", me refiero a los patrones de intentar, como los utilizados en TryParse(), y TryGetObjectByKey() métodos.

Más específicamente, qué hacer con las excepciones planteadas en los métodos de patrón 'probar' personalizados. Debo iniciar sesión, debería ignorarlo. ¿Alguien sabe cuál es la práctica con esos métodos?

+8

Si te refieres a la característica de idioma, entonces quid pro quo: dame un ejemplo de tu intento de leer la documentación: http://msdn.microsoft.com/en-us/library/0yd65esw(VS.80) .aspx –

+0

¿Te refieres a la instrucción ['try' /' catch'? ] (http://msdn.microsoft.com/en-us/library/0yd65esw.aspx) – kennytm

+2

siguiente pregunta: ¿explicar el patrón de vacío? – vidalsasoon

Respuesta

32

Aquí es un ejemplo de usando un método TryXxx:

string s = Console.ReadLine(); 
int x; 
if (int.TryParse(s, out x)) 
{ 
    Console.WriteLine("You entered the valid integer {0}", x); 
} 
else 
{ 
    Console.WriteLine("Invalid input!"); 
} 

Aquí está un ejemplo de definir el método:

bool TryParse(string s, out int x) // out parameter for result 
{ 
    if (!allCharactersAreValid(s)) 
    { 
     x = 0; 
     return false; 
    } 

    // More checks... 
    // Parse the string... 

    x = 42; 
    return true; 
} 

manejo de excepciones

La mayoría especificamente qué hacer con excepciones rised en la costumbre 'Try' métodos patrón

Su método probablemente debería evitar tirar cualquier excepción - si su usuario quería excepciones que usarían la versión no intentarlo. Por lo tanto, debe intentar evitar los métodos de llamada que pueden arrojarse al implementar su TryXxx. Sin embargo, algunas excepciones son inevitables y podrían perderse de su control, por ejemplo, OutOfMemoryException, StackOverflowException, etc. No hay nada que pueda hacer al respecto y no debería tratar de detectar estas excepciones, simplemente déjelos propagar a la persona que llama. No se los trague, no los registre, esa es la responsabilidad de quien llama.

Un ejemplo de esto es Dictionary<TKey, TValue>.TryGetValue cuando el objeto clave proporcionado a este método arroja una excepción cuando se llama al GetHashCode. Entonces la excepción resultante es no atrapado dentro del método TryGetValue - la persona que llama verá la excepción. Este código muestra que esto ocurra:

using System; 
using System.Collections.Generic; 

class Foo 
{ 
    public override int GetHashCode() 
    { 
     throw new NotImplementedException(); 
    } 
} 

class Program 
{ 
    public static void Main() 
    { 
     Dictionary<object, object> d = new Dictionary<object, object>(); 
     d["bar"] = 42; 

     object s; 
     Foo foo = new Foo(); 
     if (d.TryGetValue(foo, out s)) // results in NotImplementedException 
     { 
      Console.WriteLine("found"); 
     } 
    } 
} 
+0

gracias, pero estoy buscando la implementación de este patrón. Cómo crear métodos como TryParse(). – kofucii

+0

De hecho, muchos desarrolladores suponen que los métodos 'Try'- * son solo envoltorios para el manejo de excepciones. Eso siempre me molesta. –

+0

Nunca me gustaron los parámetros 'out', pero C# todavía no nos da mucho para resolver este problema de otra manera. – andyczerwonka

2

supongo que quiere decir algo así como Int32.TryParse o Dictionary<TKey, TValue>.TryGetValue método. Esos métodos existen para evadir el costoso lanzamiento de excepciones, y le permiten a la persona que llama conocer el error por otros medios: valor de retorno booleano en este caso.

+0

Sé para qué sirven. Estoy buscando la implementación de dicho patrón. Más específicamente, qué hacer con la excepción rised. – kofucii

+0

@kofucii: No hay excepción planteada. Las excepciones no ocurren solo, alguna pieza de código tiene que arrojarlas (unas pocas se desencadenan en la CPU, pero .NET todavía tiene código para manejar eso lanzando una excepción de .NET). La implementación es bastante simple, mueva el valor de retorno a un parámetro "out" y reemplace 'throw new WhateverException();' con 'return false;'. –

10

Espero que la implementación se parezca mucho a la versión "arrojadiza" en cada caso, excepto cuando hay una declaración "lanzar nueva FormatException" en la versión arrojada, hay "return false" ... y en el al final de la ruta de éxito, hay una asignación al parámetro de salida y "return true".

Para algunos medida se puede simular la versión de lanzamiento de la versión no tirar (aunque en términos de rendimiento no se puede hacer a la inversa) - que puede sólo llamar TryParse y lanzar una excepción si devuelve falso. Sin embargo, eso significa que la excepción no contendrá detalles sobre por qué falló el análisis.

La cantidad exacta de reutilización de código que podría lograr, a pesar de tener un buen rendimiento de la versión de prueba y excepciones detalladas en la versión de lanzamiento, dependerá de la tarea exacta en cuestión.

+0

explicación clara –

Cuestiones relacionadas