#c# #.net #loops #if-statement
#c# #.net #петли #если-заявление
Вопрос:
Код довольно прост, но не уверен, что, черт возьми, происходит. Мы очень ценим любую помощь.
Я вызываю функцию проверки, чтобы проверить, ввел ли пользователь » c » или » r » в основном методе, как это:
validation.ValidateInputChars(input, 'c', 'r');
и функция validateInputChars выглядит следующим образом:
public char ValidateInputChars(char actualInput, char input1, char input2) { if (char.Equals(actualInput, input1)) { return 'c'; } else if (char.Equals(actualInput, input2)) { return 'r'; } else { Console.WriteLine("n You pressed " actualInput "nYour input is incorrect, kindly press " input1 " or " input2 " to proceed"); actualInput = Console.ReadKey().KeyChar; ValidateInputChars(actualInput, input1, input2); return 'z'; } }
Входные данные: давайте предположим: «q», «w», «e», а затем «c».
Все работает нормально, пока я не нажму «с». Он входит в первый цикл, чтобы вернуть правильный ввод «c», но затем, как ни странно, он также переходит в цикл else, где он возвращает » z » еще 4 раза.
И, наконец, результат, который он возвращает, является вторым вводом, поэтому в этом случае он, наконец, возвращает » w » (WTH!).
Я пробовал без операторов if else, со списком {‘c’, ‘r’}, все.
Единственное, что мне нужно, — это знать, ввел ли пользователь «c» или «r», но это не работает.
Есть идеи, что здесь происходит?
Комментарии:
1.
return ValidateInputChars(actualInput, input1, input2);
вместоValidateInputChars(actualInput, input1, input2); return 'z';
Ответ №1:
Кажется, что вы хотите спрашивать пользователя снова и снова, пока не будет указан правильный символ. Если это ваш случай, то вам следует поставить
// validate actualInput again, return a valid choice return ValidateInputChars(actualInput, input1, input2);
вместо
// Validate, ignore valid choice and... ValidateInputChars(actualInput, input1, input2); // ...return 'z' (!) return 'z';
И, пожалуйста, избегайте магических запоров , таких как 'c'
, 'r'
:
if (char.Equals(actualInput, input1)) { return input1; // there's no guarantee, that input1 == 'c' } if (char.Equals(actualInput, input2)) { return input2; // there's no guarantee, that input2 == 'r' }
Я бы предпочел избавиться от рекурсии в пользу простого while
цикла:
// static: we don't want "this" in the method public static char ValidateInputChars(char actualInput, char input1, char input2) { // while actualInput is NOT correct, keep asking user while (actualInput != input1 amp;amp; actualInput != input2) { Console.WriteLine($"n You pressed {actualInput}nYour input is incorrect, kindly press {input1} or {input2} to proceed"); actualInput = Console.ReadKey().KeyChar; } return actualInput; }
Наконец, вы можете немного обобщить метод, чтобы он мог принимать произвольное количество допустимых символов:
public static char ValidateInputChars(char actualInput, params char[] validChars) { if (validChars is null) throw new ArgumentNullException(nameof(validChars)); if (validChars.Length lt;= 0) throw new ArgumentException("No valid chars are provided", nameof(validChars)); // while actualInput is NOT correct, keep asking user while (!validChars.Contains(actualInput)) { Console.WriteLine($"n You pressed {actualInput}nYour input is incorrect, kindly press {string.Join(" or ", validChars)} to proceed"); actualInput = Console.ReadKey().KeyChar; } return actualInput; }
Использование:
Console.Write("Please, press c, r, or z"); char result = ValidateInputChars(Console.ReadKey().KeyChar, 'c', 'r', 'z');
Комментарии:
1. Спасибо, в то время как цикл работал, но все еще не уверен, почему рекурсия возвращала его методу после возврата правильного значения.
2. @AdarshSharma: рекурсивный метод возвращается: представьте, что вы предоставляете правильное значение (
c
) при попытке 3d; теперь 3d atempt (рекурсивный вызов 3d) возвращает правильное значение 2-му вызову, который, в свою очередь, передает его 1-му, который, наконец, возвращает его вам.