Qual é o tipo de retorno de C # "retorno" [fechado]

9

Estou criando um aplicativo de console e tenho um "Menu" onde o usuário pode inserir informações para criar um novo objeto Pessoa. O seguinte está dentro de um 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();

igual a. Quero que o usuário possa sair do método a qualquer momento, se decidir que não quer criar uma nova pessoa. Então, eu gostaria de criar um novo método chamado "CheckExit" e, se digitar "EXIT", deixará o método "CreatePerson". Então, eu quero que o "CheckExit" retorne um retorno. Caso contrário, tenho que adicionar uma declaração "if" após cada entrada e isso fica confuso.

Isso é possível? O retorno tem um tipo de retorno? Qual seria a maneira correta de fazer isso?

Arkyris
fonte
Na mesma nota, eu nem sei se um retorno de dentro de um if funcionaria apenas para sair da instrução if. Talvez eu precise usar um goto. De qualquer maneira isso está além do ponto
Arkyris
Mas você deseja encerrar o programa ou tornar a nova pessoa uma rotina?
dcg 04/02
Termine de fazer a rotina de uma nova pessoa. Basicamente, basta ir até um menu lvl. Mas não quero fazer isso depois de cada entrada. if (fname == "EXIT") {Console.Write ("Deseja mesmo sair deste menu?"); Console.ReadLine (); Retorna; }
Arkyris
11
Você pode throw exceptionno método e returnno correspondentecatch
Dmitry Bychenko

Respostas:

8

returnnão é um tipo que você possa retornar, é uma palavra-chave para retornar um resultado. Infelizmente, o que você está tentando fazer não é possível. No entanto, você pode tornar seu código muito mais legível e extensível usando uma matriz de consultas e obtendo os resultados para cada um de um loop. Isso tem o efeito bônus de poder adicionar mais consultas com facilidade.

// 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
fonte
7
Isso não é mais legível.
user253751 4/02
Parece Javascript, não C #.
ouflak
@outflak O Microsoft C # usa o estilo Allman, mas o Mono C # também usa o estilo Java usado pelo JavaScript.
aloisdg movendo-se para codidact.com
2
@ user253751 Você não poderia estar mais errado. O código nesta resposta é muito mais simples que o código do OP, pelo motivo que o respondente explicou corretamente. E sou um forte defensor da legibilidade e manutenção como a primeira preocupação após a correção.
StackOverthrow
2
@ user253751 Uma métrica extremamente duvidosa que caiu em desuso há décadas e por boas razões.
StackOverthrow
7

Você pode criar um método para ler do console para automatizar esse processo, algo 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;
}

Então seu código ficaria assim:

try {
    string fName = ReadFromConsole("Please enter the first name: ");
    ....
}
catch (StopCreatingPersonException)
{ }
dcg
fonte
2
Interessante, eu não sabia criar minhas próprias exceções. Vou aprender mais sobre isso, obrigado.
Arkyris
@CaiusJard done! Obrigado por observar, é uma boa prática.
dcg 04/02
@CaiusJard sim, seria melhor, eu vou editar. Obrigado
dcg
11
@Arkyris, não precisa especificamente ser sua própria exceção; essa técnica funcionaria bem mesmo dizendo throw new Exception()e capturando-a. Há também uma OperationCanceledException na estrutura cujo nome talvez se encaixa no que você está tentando fazer e pode fazer sentido usar. Normalmente, lançamos diferentes tipos de exceção para que possamos diferenciar na captura de alguns e não de outros, mas, em essência, a única maneira de um sub-método retornar um método externo é o sub-método lançar, o exterior não capturar e depois controlar retornos ao método acima do externo / a "return return"
Caius Jard
11
@dgg Não use exceções para controle de fluxo e não crie classes de exceção, a menos que seja realmente necessário . Por outro lado, já vi coisas piores; Estou mantendo o código em que um programa controlado por desenvolvedor supostamente sênior flui com exceções de tipo estrito, diferenciadas por suas mensagens de erro.
StackOverthrow
1

As instruções de retorno são usadas para retornar um valor de um método que possui um tipo de retorno. Quando você escreve um método com void como o tipo de retorno, pode usar o return;para sair do método.

por exemplo, o método a seguir usa uma string como o tipo de retorno,

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

Se você estiver escrevendo um método que cria o objeto e o retorna ao método de chamada, o tipo de retorno seria a Pessoa (a menos que você pretenda fazer outra coisa). Se você verificar a entrada do usuário e decidir não criar uma Pessoa, poderá usar 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;
}

E você pode usar esse método no Main,

public static void Main(string[] args) 
{
    Person person = CreatePerson();
    if (person == null) {
       Console.WriteLine("User Exited.");
    }
    else
    {
       // Do Something with person.
    }
}
Jawad
fonte
Eles ainda teriam que reservar um tempo para inserir tudo, não precisariam?
Arkyris
se digitarem a saída a qualquer momento, isso será interrompido. return significa, deixe o método CreatePersonimediatamente.
Jawad
0

A única maneira é usar returnse você deseja finalizar o método. Mas você pode encurtar seu código de algo como isto:

    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
fonte