Al analizar la entrada del usuario, generalmente se recomienda no lanzar y capturar excepciones, sino usar métodos de validación. En .NET BCL, esta sería la diferencia entre, por ejemplo, int.Parse
(produce una excepción en datos no válidos) y int.TryParse
(devuelve false
datos no válidos).
Estoy diseñando el mío
Foo.TryParse(string s, out Foo result)
método y no estoy seguro sobre el valor de retorno. Podría usar bool
como el propio TryParse
método de .NET , pero eso no daría ninguna indicación sobre el tipo de error, sobre la razón exacta por la que s
no se puede analizar en a Foo
. (Por ejemplo, s
podría tener paréntesis sin igual, o el número incorrecto de caracteres, o un Bar
sin un correspondiente Baz
, etc.)
Como usuario de API, no me gustan mucho los métodos que solo devuelven un Booleano de éxito / fracaso sin decirme por qué falló la operación. Esto hace que la depuración sea un juego de adivinanzas, y tampoco quiero imponer eso a los clientes de mi biblioteca.
Puedo pensar en muchas soluciones a este problema (códigos de estado de retorno, devolver una cadena de error, agregar una cadena de error como parámetro de salida), pero todos tienen sus desventajas respectivas, y también quiero mantener la coherencia con las convenciones de .NET Framework .
Por lo tanto, mi pregunta es la siguiente:
¿Existen métodos en .NET Framework que (a) analicen la entrada sin generar excepciones y (b) sigan devolviendo información de error más detallada que un simple booleano verdadero / falso?
fuente
Parse()
.Respuestas:
Recomendaría usar el patrón de mónada para su tipo de retorno.
ParseResult<Foo> foo = FooParser.Parse("input");
Tenga en cuenta también que no debería ser responsabilidad de Foo averiguar cómo se debe analizar a partir de la entrada del usuario, ya que esto vincula directamente su capa de dominio a su capa de interfaz de usuario y también viola el principio de responsabilidad única.
También puede hacer una clase de resultado de análisis específica para, en
Foo
lugar de usar genéricos, según su caso de uso.Una clase de resultado de análisis específico foo podría verse así:
Aquí está la versión de Monad:
No conozco ningún método en el marco .net que devuelva información detallada de error de análisis.
fuente
Foo.ToString
yFoo.Parse
.Func<T>
cumpliría ese criterio, si incluye enT
la información que necesita. Devolver información detallada sobre errores depende en gran medida de usted. ¿Has considerado usar unMaybe<T>
? Ver mikhail.io/2016/01/monads-explained-in-csharpPodrías mirar ModelState en el marco MVC. Representa un intento de análisis de alguna entrada y puede tener una colección de errores.
Dicho esto, no creo que haya un patrón recurrente para esto en .net BCL, ya que las excepciones son, para bien o para mal, el patrón establecido para informar condiciones de error en .net. Creo que debería seguir adelante e implementar su propia solución que se adapte a su problema, por ejemplo, una
ParseResult
clase con dos subclasesSuccessfulParse
yFailedParse
, dondeSuccessfulParse
tiene una propiedad con el valor analizado yFailedParse
tiene una propiedad de mensaje de error. Combinar esto con la coincidencia de patrones en C # 7 podría ser bastante elegante.fuente
Me he encontrado con problemas similares al querer usar un
TryParse/Convert/etc.
método en el que a veces necesito saber cómo y por qué falló.Terminé inspirándome en cómo algunos serializadores manejan errores y usan eventos. De esta manera, la sintaxis de mi
TryX(..., out T)
método se ve tan limpia como cualquier otra y devuelve de manera confiable un simplefalse
como lo implica el patrón.Sin embargo, cuando quiero necesitar más detalles, solo agrego un controlador de eventos y obtengo los resultados que necesito en un paquete tan complejo o simple como quiero (el
MyEventArgs
siguiente). Agréguelo a una lista de cadenas, agregueExceptionDispatchInfo
y capture Excepciones; deje que la persona que llama decida si quiere lidiar con algo que sale mal y cómo lo hará.fuente