EDIT: estoy agregando un resumen de mi punto en la parte superior, para facilitar la lectura:
Si el método se vuelve múltiples piezas de datos que son lógicamente todos parte de la misma "cosa", entonces definitivamente componerlos en un objeto complejo independientemente de si está devolviendo ese objeto como el valor de retorno o un parámetro de salida.
Si su método necesita devolver algún tipo de estado (éxito/falla/cuántos registros se actualizaron/etc.) Además de los datos, y luego considerar regresar a sus datos como un parámetro de salida y utilizando el valor de retorno para volver al estado
Hay dos variaciones de las situaciones a las que se aplica esta pregunta:
Necesidad de devolver los datos que consta de varios atributos
Necesitando para devolver datos junto con un estado de la acción utilizado para obtener que los datos
Para el n. ° 1, mi opinión es que si tiene datos que constan de múltiples atributos que van todos juntos, entonces deben estar compuestos en un solo tipo como clase o estructura, y debe devolverse un solo objeto como el valor de retorno de un método o como un parámetro de salida.
Para el n. ° 2, creo que este es el caso donde los parámetros de salida realmente tienen sentido. Conceptualmente, los métodos típicamente realizan una acción; en este caso, prefiero usar el valor de retorno del método para indicar el estado de la acción. Eso podría ser un booleano simple para indicar el éxito o el fracaso, o podría ser algo más complicado, como una enumeración o una cadena, si existen múltiples estados posibles para describir la acción que realizó el método.
Si utilizo los parámetros de salida, recomendaría que una persona use solo uno (consulte el punto n. ° 1), a menos que haya una razón específica para usar más de uno. No use múltiples parámetros de salida simplemente porque los datos que necesita devolver consisten en múltiples atributos. Solo use múltiples parámetros de salida si la semántica de su método lo dicta específicamente. A continuación se muestra un ejemplo en el que creo múltiples parámetros de salida tienen sentido:
// an acceptable use of multiple output parameters
bool DetermineWinners(IEnumerable<Player> players, out Player first, out Player second, out Player third)
{
// ...
}
Por el contrario, aquí se muestra un ejemplo en el que creo múltiples parámetros de salida no tienen sentido.
// Baaaaad
bool FindPerson(string firstName, string lastName, out int personId, out string address, out string phoneNumber)
{
// ...
}
Los atributos de los datos (personId, dirección, y phoneNumber) debe ser parte de un objeto Person devuelto por el método. Una mejor versión sería la siguiente:
// better
bool FindPerson(string firstName, string lastName, out Person person)
{
// ...
}
Me gusta la parte del objeto complejo, pero ¿cuándo 'tienes que' usar un parámetro out? –
Me parece muy raro. Usualmente donde tengo que devolver dos tipos diferentes y prefiero no crear un tercer tipo para contener esos dos solo para los propósitos de la operación. Sé que suena vago, pero probablemente podría contar con las dos manos las veces que 'tuve que' hacer eso. Intento evitarlo si puedo. –
Es posible que desee echar un vistazo a mi respuesta para ver mi discusión sobre cuándo los parámetros de salida tienen sentido. Tenga en cuenta que mi punto principal es que el uso de objetos complejos y el uso de parámetros de salida no son mutuamente excluyentes. –