Приставка.ReadKey хранит старые ключи и возвращает их после успешного истинного возврата в c#

#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-му, который, наконец, возвращает его вам.