Escribí una función en C# que inicialmente devolvía una tupla con nombre. Pero ahora, solo necesito un campo de esta tupla y me gustaría mantener el nombre porque me ayuda a entender mi código.
private static (bool informationAboutTheExecution, bool field2thatIdontNeedAnymore) doSomething() { // do something return (true, false); }Esta función compila. Pero es la siguiente función que quiero
private static (bool informationAboutTheExecution) doSomething() { // do something return (true); }los mensajes de error:
Tupla debe contener al menos dos elementos
no se puede convertir implícitamente el tipo 'bool' a '(informaciónSobreLaEjecución,?)
¿Alguien tiene una solución para mantener el nombre del valor devuelto?
No puedes, básicamente. Puede devolver un ValueTuple<bool> , pero eso no tiene nombres. No puede agregar [return:TupleElementNamesAttribute] manualmente, ya que el compilador explícitamente no lo permite (CS8138). Podrías simplemente devolver bool . Puede hacer lo siguiente, pero no es más útil que simplemente devolver bool :
private static ValueTuple<bool> doSomething() => new ValueTuple<bool>(true); Parte del problema es que ({some expression}) ya es una expresión válida antes de que se introdujera la sintaxis de tupla de valor, razón por la cual
private static ValueTuple<bool> doSomething() => (true);No se permite.
Si debe nombrar su declaración, puede hacer esto:
private static void doSomething(out bool information) { // do something information = true; }entonces llámalo con
bool result; doSomething(out result);Solo quiero agregar otra opción, aunque él out es la solución más fácil y Marc ya explicó por qué no es posible. Simplemente crearía una clase para ello:
public class ExecutionResult { public bool InformationAboutTheExecution { get; set; } } private static ExecutionResult DoSomething() { // do something return new ExecutionResult{ InformationAboutTheExecution = true }; }La clase se puede extender fácilmente y también puede asegurarse de que nunca sea nula y se pueda crear con métodos de fábrica como estos, por ejemplo:
public class SuccessfulExecution: ExecutionResult { public static ExecutionResult Create() => new ExecutionResult{ InformationAboutTheExecution = true }; } public class FailedExecution : ExecutionResult { public static ExecutionResult Create() => new ExecutionResult { InformationAboutTheExecution = false }; }Ahora puedes escribir código como este:
private static ExecutionResult DoSomething() { // do something return SuccessfulExecution.Create(); } y en caso de error (por ejemplo) puede agregar una propiedad ErrorMesage :
private static ExecutionResult DoSomething() { try { // do something return SuccessfulExecution.Create(); } catch(Exception ex) { // build your error-message here and log it also return FailedExecution.Create(errorMessage); } }