¿Cuál es el tipo de retorno de "retorno" C # [cerrado]

9

Estoy creando una aplicación de consola y tengo un "Menú" donde el usuario puede ingresar información para crear un nuevo objeto Persona. Lo siguiente está dentro de un método.

        Write("Please enter the first name: ", false);
        string fName = Console.ReadLine().ToUpper();
        Write("Please enter the middle initial: ", false);
        string mInitial = Console.ReadLine().ToUpper();
        Write("Please enter the last name: ", false);
        string lName = Console.ReadLine().ToUpper();

al igual que. Quiero que el usuario pueda salir del método en cualquier momento si decide que no quiere crear una nueva persona. Así que me gustaría crear un nuevo método llamado "CheckExit" y si escriben "EXIT" dejará el método "CreatePerson". Entonces quiero que el "CheckExit" devuelva un retorno. De lo contrario, tengo que agregar una declaración "if" después de cada entrada y eso se vuelve desordenado.

es posible? ¿La devolución tiene un tipo de devolución? ¿Cuál sería la forma correcta de hacer esto?

Arkyris
fuente
En esa nota, ni siquiera sé si un retorno desde dentro de un if funcionaría simplemente saliendo de la declaración if. Puede que tenga que usar un goto. De todos modos, eso no viene al caso
Arkyris
¿Pero quieres terminar el programa o terminar haciendo que la nueva persona sea una rutina?
dcg
Termine de hacer una nueva persona rutina. Básicamente solo sube un menú lvl. Pero no quiero tener que hacer esto después de cada entrada. if (fname == "EXIT") {Console.Write ("¿Realmente quieres salir de este menú?"); Console.ReadLine (); regreso; }
Arkyris
1
Puede throw exceptionen el método y returnen el correspondientecatch
Dmitry Bychenko

Respuestas:

8

returnno es un tipo que puede devolver, es una palabra clave para devolver un resultado. Desafortunadamente, lo que está tratando de hacer no es posible. Sin embargo, puede hacer que su código sea mucho más legible y ampliable mediante el uso de una serie de consultas y obtener los resultados para cada uno dentro de un bucle. Esto tiene el efecto adicional de poder agregar más consultas con facilidad.

// you can put these queries somewhere outside the function
string[] queries = {"Please enter the first name: ", ...}
var results = new List<string>();

foreach (string query in queries) {
    Write(query, false);
    var result = Console.ReadLine().ToUpper();
    if (result.Equals("EXIT") {
        return;
    }
    results.Add(result);
}

// handle your inputs from the results list here ...
J. Schultke
fuente
77
Esto no es más legible.
user253751
Esto parece Javascript, no C #.
ouflak
@outflak Microsoft C # usa el estilo Allman, pero Mono C # también usa el estilo Java usado por JavaScript.
aloisdg se muda a codidact.com
2
@ user253751 No podría estar más equivocado. El código en esta respuesta es mucho más simple que el código del OP, por la razón que el respondedor explicó correctamente. Y soy un firme defensor de la legibilidad y la facilidad de mantenimiento como la primera preocupación después de la corrección.
StackOverthrow
2
@ user253751 Una métrica extremadamente dudosa que dejó de usarse hace décadas, y por una buena razón.
StackOverthrow
7

Podría crear un método para leer desde la consola para automatizar este proceso, algo así como

internal class StopCreatingPersonException : Exception
{}

public static string ReadFromConsole(string prompt)
{
     Write(prompt, false);
     var v = Console.ReadLine().ToUpper();
     if (v == "EXIT") { throw new StopCreatingPerson (); }
     return v;
}

Entonces su código se vería así:

try {
    string fName = ReadFromConsole("Please enter the first name: ");
    ....
}
catch (StopCreatingPersonException)
{ }
dcg
fuente
2
Interesante, no tenía conocimiento de crear mis propias excepciones. Aprenderé más sobre esto gracias.
Arkyris
@CaiusJard hecho! Gracias por señalar, es una buena práctica.
dcg
@CaiusJard sí, sería mejor, editaré. Gracias
dcg
1
@Arkyris no tiene que ser específicamente tu propia excepción; Esta técnica funcionaría bien incluso con solo decirla throw new Exception()y atraparla. También hay una OperationCanceledException en el marco cuyo nombre quizás se ajusta a lo que está intentando hacer y podría tener sentido usar. Por lo general, lanzamos diferentes tipos de Excepción para que podamos diferenciar la captura de algunos y no de otros, pero en esencia, la única forma para que un método secundario haga un retorno del método externo es que el método secundario arroje, el externo no atrape y luego controle los retornos al método sobre el exterior / a "return return"
Caius Jard
1
@dgg No use excepciones para el control de flujo y no cree clases de excepción a menos que sea realmente necesario . Por otro lado, he visto aún peor; Mantengo el código donde un flujo de programa controlado por un desarrollador supuestamente senior con excepciones tipadas se distingue por sus mensajes de error.
StackOverthrow
1

Las declaraciones de retorno se utilizan para devolver un valor de un método que tiene un tipo de retorno. Cuando escribe un método con void como tipo de retorno, puede usar return;para salir del método.

por ejemplo, el siguiente método usa una cadena como tipo de retorno,

public string ReturnString() { return "thisString"; }

Si está escribiendo un método que crea el objeto y lo devuelve al método de llamada, entonces el tipo de retorno sería la Persona (a menos que tenga la intención de hacer otra cosa). Si verifica la entrada del usuario y decide no crear una Persona, puede usarla return null;.

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Initial { get; set; }
}

public static Person CreatePerson()
{
    Person person = new Person();
    Console.Write("Please enter the first name: ", false);
    string fName = Console.ReadLine().ToUpper();
    if (string.IsNullOrEmpty(fName) || fName.ToLower().Equals("exit"))
        return null;
    person.FirstName = fName;

    Console.Write("Please enter the middle initial: ", false);
    string mInitial = Console.ReadLine().ToUpper();
    if (string.IsNullOrEmpty(mInitial) || mInitial.ToLower().Equals("exit"))
        return null;
    person.Initial = mInitial;

    Console.Write("Please enter the last name: ", false);
    string lName = Console.ReadLine().ToUpper();
    if (string.IsNullOrEmpty(lName) || lName.ToLower().Equals("exit"))
        return null;
    person.LastName = lName;

    return person;
}

Y puedes usar este método en Main,

public static void Main(string[] args) 
{
    Person person = CreatePerson();
    if (person == null) {
       Console.WriteLine("User Exited.");
    }
    else
    {
       // Do Something with person.
    }
}
Jawad
fuente
Todavía tendrían que tomarse el tiempo para ingresar todo, ¿no?
Arkyris
si escriben la salida en cualquier momento, se detendría. retorno significa, abandone el método de CreatePersoninmediato.
Jawad
0

La única forma es usarlo returnsi desea terminar el método. Pero puedes acortar tu código de esta manera:

    static void Main(string[] args)
    {
        createPerson();

        Console.WriteLine("Some display goes here...");
    }

    static void createPerson()
    {
        Console.WriteLine("Please enter the first name: ");
        string fName = getInput();
        if (isExit(fName))
        {
            return;
        }

        Console.WriteLine("Please enter the middle initial: ");
        string mInitial = getInput();
        if (isExit(mInitial))
        {
            return;
        }

        Console.WriteLine("Please enter the last name: ");
        string lName = getInput();
        if (isExit(lName))
        {
            return;
        }
    }

    static string getInput()
    {
        return Console.ReadLine().ToUpper();
    }

    static bool isExit(string value)
    {
        if (value == "EXIT")
        {
            Console.WriteLine("Create person has been canceled by the user.");
            return true;
        }
        return false;
    }
Jonel Zape
fuente