funciones español c# methods return-value

español - public void c#



Cómo indicar que un método no tuvo éxito (16)

¿Por qué iban a fallar? Si se debe a algo que ha hecho la persona que llama (es decir, los argumentos proporcionados), arrojar ArgumentException es totalmente apropiado. Un método Try [...] que evita la excepción está bien.

Creo que es una buena idea proporcionar la versión que arroja una excepción, de modo que las personas que llaman que esperan que siempre proporcionen buenos datos recibirán un mensaje adecuadamente fuerte (es decir, una excepción) si alguna vez se equivocan.

Tengo varios métodos similares, por ejemplo, p. Ej. CalculatePoint (...) y CalculateListOfPoints (...). Ocasionalmente, es posible que no tengan éxito, y es necesario que se lo indique a la persona que llama. Para CalculateListOfPoints, que devuelve una lista genérica, podría devolver una lista vacía y exigir que la persona que llama compruebe esto; sin embargo, Point es un tipo de valor y, por lo tanto, no puedo devolver nulo allí.

Idealmente, me gustaría que los métodos parezcan similares; Una solución podría ser definirlos como

public Point CalculatePoint(... out Boolean boSuccess); public List<Point> CalculateListOfPoints(... out Boolean boSuccess);

o alternativamente para devolver un punto? para CalculatePoint, y devuelve null para indicar la falla. Sin embargo, eso significaría tener que recurrir al tipo no nulable, que parece excesivo.

Otra ruta sería devolver el BoSuccess Boolean, tener el resultado (Point o List) como un parámetro ''out'', y llamarlos TryToCalculatePoint o algo así ...

¿Cuál es la mejor práctica?

Editar: ¡No quiero usar Excepciones para el control de flujo! El fracaso a veces se espera.


Bien con Point, puede enviar Point.Empty como valor de retorno en caso de falla. Ahora todo lo que realmente hace es devolver un punto con 0 para el valor X e Y, así que si ese puede ser un valor de retorno válido, me mantendría alejado de eso, pero si su método nunca devolverá un punto (0,0) , entonces puedes usar eso.


Diría que la mejor práctica es un valor de retorno que significa éxito, y una excepción significa fracaso.

No veo ninguna razón en los ejemplos que proporcionó que no deba usar excepciones en caso de error.


El bool TrySomething () es al menos una práctica, que funciona bien para los métodos de análisis de .net, pero no creo que me guste en general.

Lanzar una excepción a menudo es algo bueno, aunque no debe usarse para las situaciones que esperarías que ocurriera en muchas situaciones normales, y tiene un costo de rendimiento asociado.

En la mayoría de los casos, devolver el valor nulo es posible, cuando no desea una excepción.

Sin embargo , su enfoque es un poco de procedimiento, ¿qué pasa con la creación de algo así como una clase PointCalculator, tomando los datos requeridos como parámetros en el constructor? A continuación, llama a CalculatePoint y accede al resultado a través de propiedades (propiedades separadas para Point y para Success).


El modelo que he usado es el mismo que MS usa con los métodos TryParse de varias clases.

Tu código original:
punto público CalculatePoint (... out Boolean boSuccess);
public List CalculateListOfPoints (... out Boolean boSuccess);

Se convertiría en bool público CalculatePoint (... fuera (o ref) Point CalculatedValue);
public bool CalculateListOfPoints (... salir (o ref) Listar valores calculados);

Básicamente, haces del éxito / fracaso el valor de retorno.


En su mayoría depende del comportamiento de sus métodos y su uso.

Si el error es común y no crítico, entonces haga que sus métodos den como resultado un booleano que indique su éxito y use un parámetro de salida para transmitir el resultado. Al buscar una clave en un hash, intentar leer datos en un socket no bloqueante cuando no hay datos disponibles, todos estos ejemplos caen en esa categoría.

Si la falla es inesperada, devuelva directamente el resultado y transmita los errores con excepciones. Abrir un archivo de solo lectura, conectarse a un servidor TCP, son buenos candidatos.

Y a veces ambos caminos tienen sentido ...


No desea lanzar excepciones cuando se espera que ocurra algo, ya que @Kevin dijo que las excepciones son para casos excepcionales.

Debe devolver algo que se espera para el ''fracaso'', generalmente nulo es mi elección de mal rendimiento.

La documentación de su método debe informar a los usuarios qué esperar cuando los datos no se computan .


Otra alternativa es arrojar una excepción. Sin embargo, generalmente solo desea lanzar excepciones en "casos excepcionales".

Si los casos de falla son comunes (y no excepcionales), entonces ya ha enumerado sus dos opciones. EDITAR : Puede haber una convención en su proyecto sobre cómo manejar tales casos no excepcionales (si uno debe devolver el éxito o el objeto). Si no existe una convención existente, entonces estoy de acuerdo con lucasbfr y sugiero que devuelva el éxito (lo cual concuerda con la forma en que TryParse (...) está diseñado).


Para resumir, hay un par de enfoques que puede tomar:

  1. Cuando el tipo de devolución es un tipo de valor, como Punto, use la función Nullable de C # y devuelva un Punto? (también conocido como Nullable), de esa manera todavía puede devolver nulo en una falla
  2. Lanza una excepción cuando hay una falla. Todo el argumento / discusión con respecto a lo que es y no es "excepcional" es un punto discutible, es su API, usted decide qué comportamiento es excepcional.
  3. Adopte un modelo similar al implementado por Microsoft en los tipos base como Int32, proporcione un CalculatePoint y TryCalculatePoint (int32.Parse e int32.TryParse) y tenga un lanzamiento y uno devuelva un bool.
  4. Devuelve una estructura genérica de tus métodos que tiene dos propiedades, bool Success y GenericType Value.

Dependiendo del escenario, suelo usar una combinación de devolver nulo o lanzar una excepción ya que me parecen "más limpios" y se ajustan mejor a la base de código existente en la empresa para la que trabajo. Entonces mi mejor práctica personal sería los enfoques 1 y 2.


Personalmente, creo que usaría la misma idea que TryParse (): usar un parámetro out para generar el valor real y devolver un booleano que indique si la llamada fue exitosa o no.

public bool CalculatePoint(... out Point result);

No soy partidario de usar excepciones para comportamientos "normales" (si espera que la función no funcione para algunas entradas).


Si la falla es por una razón específica, entonces creo que está bien devolver null, o bool y tener un parámetro out. Sin embargo, si devuelve nulo independientemente de la falla, entonces no lo recomiendo. Las excepciones proporcionan un amplio conjunto de información que incluye la razón por la que algo falló, si todo lo que recibe es un valor nulo, entonces, ¿cómo sabe si es porque los datos son incorrectos, se ha quedado sin memoria o algún otro comportamiento extraño?

Incluso en .net, el TryParse tiene un hermano Parse para que pueda obtener la excepción si así lo desea.

Si proporcioné un método TrySomething, también proporcionaría un método Something que lanzó una excepción en caso de error. Entonces depende de la persona que llama.


Un patrón con el que estoy experimentando es devolver un Tal vez . Tiene la semántica del patrón TryParse , pero una firma similar al patrón null-return-on-error.

Todavía no estoy convencido de una manera u otra, pero lo ofrezco para su consideración colectiva. Tiene el beneficio de no requerir una variable definida antes de la llamada al método para mantener el parámetro out en el sitio de llamada del método. También podría extenderse con una colección de errores o mensajes para indicar el motivo de la falla.

La clase Maybe se ve así:

/// <summary> /// Represents the return value from an operation that might fail /// </summary> /// <typeparam name="T"></typeparam> public struct Maybe<T> { T _value; bool _hasValue; public Maybe(T value) { _value = value; _hasValue = true; } public Maybe() { _hasValue = false; _value = default(T); } public bool Success { get { return _hasValue; } } public T Value { get { // could throw an exception if _hasValue is false return _value; } } }


Una vez escribimos un Framework completo donde todos los métodos públicos devolvían verdadero (se ejecutó con éxito) o falso (se produjo un error). Si necesitábamos devolver un valor, utilizamos los parámetros de salida. Contrariamente a la creencia popular, esta forma de programación simplificó mucho nuestro código.


Usar una excepción es una mala idea en algunos casos (especialmente cuando se escribe un servidor). Necesitarás dos sabores del método. También mire la clase del diccionario para una indicación de lo que debe hacer.

// NB: A bool is the return value. // This makes it possible to put this beast in if statements. public bool TryCalculatePoint(... out Point result) { } public Point CalculatePoint(...) { Point result; if(!TryCalculatePoint(... out result)) throw new BogusPointException(); return result; }

¡Lo mejor de ambos mundos!


Punto de retorno. Vacío . Es un patrón de diseño .NET para devolver un campo especial cuando desea verificar si la creación de la estructura fue exitosa. Evite los parámetros cuando pueda.

public static readonly Point Empty


Lo siento, acabo de recordar el tipo Nullable, deberías ver eso. Aunque no estoy muy seguro de lo que es la sobrecarga.