Jaki jest typ zwrotu „return” C # [zamknięty]

9

Tworzę aplikację konsolową i mam „Menu”, w którym użytkownik może wprowadzić informacje, aby utworzyć nowy obiekt Person. Poniżej przedstawiono metodę.

        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();

lubię to. Chcę, aby użytkownik mógł w dowolnym momencie wyjść z metody, jeśli zdecyduje, że nie chce tworzyć nowej osoby. Chciałbym więc stworzyć nową metodę o nazwie „CheckExit”, a jeśli wpisze „EXIT”, opuści metodę „CreatePerson”. Chcę więc, aby „CheckExit” zwrócił zwrot. W przeciwnym razie muszę dodawać instrukcję „if” po każdym wejściu, co powoduje bałagan.

czy to możliwe? Czy zwrot ma typ zwrotu? Jaki byłby właściwy sposób to zrobić?

Arkyris
źródło
W tej notatce nawet nie wiem, czy powrót z wnętrza if działałby po prostu, jeśli wyjdzie z instrukcji if. Może będę musiał użyć goto. W każdym razie to poza tym
Arkyris
Ale chcesz zakończyć program lub zakończyć rutynę dla nowej osoby?
dcg
Zakończ rutynę nowej osoby. Zasadniczo wystarczy wejść na wyższy poziom menu. Ale nie chcę tego robić po każdym wpisie. if (fname == „EXIT”) {Console.Write („Czy naprawdę chcesz opuścić to menu?”); Console.ReadLine (); powrót; }
Arkyris
1
Możesz throw exceptionw metodzie iw returnodpowiednimcatch
Dmitrij Bychenko

Odpowiedzi:

8

returnnie jest typem, który możesz zwrócić, to słowo kluczowe do zwrócenia wyniku. Niestety, to, co próbujesz zrobić, nie jest możliwe. Możesz jednak uczynić kod znacznie bardziej czytelnym i rozszerzalnym, korzystając z tablicy zapytań i uzyskując wyniki dla każdego wnętrza pętli. Daje to dodatkowy efekt łatwego dodawania kolejnych zapytań.

// 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
źródło
7
To nie jest bardziej czytelne.
user253751
To wygląda jak Javascript, a nie C #.
ouflak
@outflak Microsoft C # używa stylu Allman, ale Mono C # również używa stylu Java używanego przez JavaScript.
aloisdg przechodzi na codidact.com
2
@ user253751 Nie możesz się bardziej mylić. Kod w tej odpowiedzi jest znacznie prostszy niż kod PO, z tego powodu, że odpowiadający poprawnie wyjaśnił. A ja jestem zwolennikiem czytelności i łatwości konserwacji jako pierwszego problemu po poprawności.
StackOverthrow
2
@ user253751 Niezwykle wątpliwy wskaźnik, który przestał być używany kilkadziesiąt lat temu i nie bez powodu.
StackOverthrow
7

Możesz stworzyć metodę odczytu z konsoli, aby zautomatyzować ten proces, coś w rodzaju

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;
}

Twój kod wyglądałby następująco:

try {
    string fName = ReadFromConsole("Please enter the first name: ");
    ....
}
catch (StopCreatingPersonException)
{ }
dcg
źródło
2
Ciekawe, że nie wiedziałem o tworzeniu własnych wyjątków. Dowiem się więcej o tym, dziękuję.
Arkyris
@CaiusJard gotowe! Dzięki za zwrócenie uwagi, to dobra praktyka.
dcg
@CaiusJard tak, byłoby lepiej, będę edytować. Dzięki
dcg
1
@Arkyris nie musi to być twój wyjątek; ta technika działałaby dobrze nawet po prostu mówiąc throw new Exception()i łapiąc ją. W frameworku znajduje się także wyjątek OperationCanceledException, którego nazwa prawdopodobnie pasuje do tego, co próbujesz zrobić i może mieć sens z jego użycia. Zwykle rzucamy różne typy wyjątków, abyśmy mogli rozróżnić łapanie niektórych, a nie innych, ale w zasadzie jedynym sposobem na powrót metody podrzędnej do metody zewnętrznej jest rzut metody podrzędnej, funkcja zewnętrzna nie przechwytuje, a następnie zwraca kontrolę do metody nad zewnętrznym / „return return”
Caius Jard
1
@dgg Nie używaj wyjątków do kontroli przepływu i nie twórz klas wyjątków, chyba że jest to naprawdę konieczne . Z drugiej strony widziałem jeszcze gorzej; Utrzymuję kod, w którym rzekomo starszy programista kontroluje przepływ programu z wyjątkami o wąskim typie, rozróżnianymi przez komunikaty o błędach.
StackOverthrow
1

Instrukcje return służą do zwracania wartości z metody, która ma typ zwracany. Kiedy piszesz metodę z void jako typem zwracanym, możesz użyć return;do wyjścia z metody

np. następująca metoda używa łańcucha jako typu zwracanego,

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

Jeśli piszesz metodę, która tworzy obiekt i zwraca go do metody wywołującej, wówczas zwracanym typem będzie Osoba (chyba że masz zamiar zrobić coś innego). Jeśli sprawdzisz dane wprowadzone przez użytkownika i zdecydujesz, że nie chcesz utworzyć Osoby, możesz użyć 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;
}

I możesz użyć tej metody w Main,

public static void Main(string[] args) 
{
    Person person = CreatePerson();
    if (person == null) {
       Console.WriteLine("User Exited.");
    }
    else
    {
       // Do Something with person.
    }
}
Jawad
źródło
Wciąż musieliby poświęcić czas na wejście do wszystkiego, prawda?
Arkyris
jeśli w dowolnym momencie wpisze wyjście, to przestanie. return oznacza, CreatePersonnatychmiast opuść metodę .
Jawad
0

Jedynym sposobem jest użycie, returnjeśli chcesz zakończyć metodę. Ale możesz skrócić swój kod coś takiego:

    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
źródło