У меня есть повторяющийся код здесь, полный goto
которые делают это, пока цикл хорошо... Повторите навсегда.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace test
{
class Program
{
static void Main(string[] args)
{
main();
}
public static ConsoleKeyInfo keyPressed;
private static void main()
{
start:
keyPressed = Console.ReadKey();
while (true)
{
loopstart:
if (keyPressed.Key == ConsoleKey.Enter)
{
Console.WriteLine("You pressed the Enter Key!");
goto loopstart;
}
if (keyPressed.Key == ConsoleKey.Escape)
{
Console.WriteLine("You pressed the Escape Key!");
goto loopstart;
}
if (keyPressed.Key == ConsoleKey.Spacebar)
{
Console.WriteLine("You pressed the Spacebar!");
goto loopstart;
}
else
{
break;
}
}
Console.WriteLine("You broke the loop!");
goto start;
}
}
}
Не удаляя код, можно ли изменить значение keyPressed.Key
или keyPressed
до NULL
; состояние, которое было, когда оно было объявлено, или любому другому значению/ключу, а не пробелу, ввести ключ или выйти из него?
Конечно, проблема может быть решена путем удаления всего goto loopstart;
начала goto loopstart;
в коде, но это касается вопроса.
То, что я хочу сделать, это сделать keyPressed.Key
значением NULL
(или любым другим значением), чтобы все операторы IF
приводили к ложному, что означает, что не выполняется код goto loopstart
цикла goto loopstart
.
Проблема в том, что когда я пытаюсь свести ее на нет с помощью простого keyPressed = null;
, он приходит с ошибкой:
Невозможно преобразовать значение null в 'System.ConsoleKeyInfo', потому что это тип значения, не равный нулю.
Есть ли способ, которым я могу скрыть (или изменить значение на что-то еще), чтобы я мог разбить цикл?
(Как в: Сделать оператор IF
доходить до точки, где он должен запускать код else
)
Он должен выглядеть примерно так:
...
{
loopstart:
if (keyPressed.Key == ConsoleKey.Enter)
{
Console.WriteLine("You pressed the Enter Key!");
// keyPressed = null; <-- Does not work.
// Do something to make ConsoleKey.Key to equal something else.
goto loopstart;
}
if (keyPressed.Key == ConsoleKey.Escape)
{
Console.WriteLine("You pressed the Escape Key!");
...
Очевидно, с помощью //Do something to make ConsoleKey.Key to equal something else.
заменен рабочим кодом?
Если это работает, при первом запуске цикла (предполагается, что клавиша, нажатая в начале, - это либо пробел, либо Escape, либо Enter), приведет к goto loopstart;
цикла goto loopstart;
и второй тайм-раунд пропустит до начала goto start;
где он попросит другой ключ.
И затем процесс повторяется со скоростью, с которой пользователь вводит ввод, а не повторяется с одним и тем же ключом без остановки или запрашивает другой ключ.
В принципе: сделайте цикл, запустив оператор IF
как правильный оператор IF
вместо цикла FOR
.
Зачем использовать goto
-statement, это очень устаревшая структура. Вы можете легко continue
цикл. И else
проверка также избыточна. Вы можете просто прочитать ключ из Console
перед проверкой, например:
while (true)
{
keyPressed = Console.ReadKey();
switch (keyPressed.Key)
{
case ConsoleKey.Enter:
Console.WriteLine("You pressed the Enter Key!");
continue;
case ConsoleKey.Escape:
Console.WriteLine("You pressed the Escape Key!");
continue;
case ConsoleKey.Spacebar:
Console.WriteLine("You pressed the Spacebar!");
continue;
}
// should be outside the switch for breaking the loop
break;
}
Если вы хотите очистить keyPressed
, используйте конструкцию по default
, например:
keyPressed = default(ConsoleKeyInfo);
Но почему вы хотите это сделать? Мусорная коллекция очистит память сама по себе, вы не должны туда заходить.
for
вместо оператора if
.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace test
{
class Program
{
static void Main(string[] args)
{
main();
}
public static ConsoleKeyInfo keyPressed;
private static void main()
{
start:
keyPressed = Console.ReadKey();
while (true)
{
loopstart:
if (keyPressed.Key == ConsoleKey.Enter)
{
Console.WriteLine("You pressed the Enter Key!");
keyPressed = new ConsoleKeyInfo('a', ConsoleKey.A, false, false, false);
goto loopstart;
}
if (keyPressed.Key == ConsoleKey.Escape)
{
Console.WriteLine("You pressed the Escape Key!");
goto loopstart;
}
if (keyPressed.Key == ConsoleKey.Spacebar)
{
Console.WriteLine("You pressed the Spacebar!");
goto loopstart;
}
else
{
break;
}
}
Console.WriteLine("You broke the loop!");
goto start;
}
}
}
Console.ReadKey();
делается в одном классе, а цикл - в другом. Таким образом, очевидно, что нет способа разорвать цикл, не возвращаясь к первому классу.