在开关盒状态下写入开关盒状态的可能性?

时间:2017-04-28 10:39:33

标签: c# .net switch-statement

我有这个代码以它应该的方式运行。但是,如果用户在插入第一个值后单击1,2或3,我希望实现额外的功能。正如您所看到的,如果用户第二次按下2,将显示名字的玩家列表(至少这是我的意图)。所以我的问题是,如果可以通过在前一个中插入switch-case条件来完成此操作?我尝试过这样的事情:请参阅下面的更多代码。

 var isValidMenuItem = false;

        while (!isValidMenuItem)
            isValidMenuItem = Menu();

        Console.WriteLine();
        Console.ReadKey(true);

    }

    private static bool Menu()
    {
        Console.WriteLine("You have now entered the 2017 Wimbledon tournament!" + "\n" + "\n");
        Console.Write("Choose one of the 6 options:" + "\n" + "Press 1 for Default tournament:" + "\n" + "Press 2 for Women's single:" + "\n" +
            "Press 3 for Men's single:" + "\n" + "Press 4 for Women's double:" + "\n" + "Press 5 for Men's double:" + "\n" +
            "Press 6 for Mix double:" + "\n" + "Insert your choice...: ");

        var userValue = Console.ReadKey().KeyChar;
        Console.WriteLine();

        switch (userValue)
        {
            case '1':
                Console.WriteLine("\n"+ "You have entered a default tournament");
                break;
            case '2':
                Console.WriteLine("\n" + "You have entered women's single");
                Console.Write("Press 1 to start the tournament:" + "\n" + "Press 2 to list the players by first name:" + "\n" + 
                    "Press 3 to list the players by last name:" + "\n" + "Insert your choice...: ");
                break;
            case '3':
                Console.WriteLine("\n" + "You have entered men's single");
                Console.Write("Press 1 to start the tournament:" + "\n" + "Press 2 to list the players by first name:" + "\n" +
                    "Press 3 to list the players by last name:" + "\n" + "Insert your choice...: ");
                break;
            case '4':
                Console.WriteLine("\n" + "You have entered women's double");
                Console.Write("Press 1 to start the tournament:" + "\n" + "Press 2 to list the players by first name:" + "\n" +
                    "Press 3 to list the players by last name:" + "\n" + "Insert your choice...: ");
                break;
            case '5':
                Console.WriteLine("\n" + "You have entered men's double");
                Console.Write("Press 1 to start the tournament:" + "\n" + "Press 2 to list the players by first name:" + "\n" +
                    "Press 3 to list the players by last name:" + "\n" + "Insert your choice...: ");
                break;
            case '6':
                Console.WriteLine("\n" + "You have entered mix double");
                Console.Write("Press 1 to start the tournament:" + "\n" + "Press 2 to list the players by first name:" + "\n" +
                    "Press 3 to list the players by last name:" + "\n" + "Insert your choice...: ");
                break;
            default:
                Console.WriteLine("\n" + "Sorry! You have to choose one of the 6 tournament options");
                return false;
        }

像这样:......但它似乎不起作用?你们有什么想法吗?

         case '2':
                Console.WriteLine("\n" + "You have entered women's single");
                Console.Write("Press 1 to start the tournament:" + "\n" + "Press 2 to list the players by first name:" + "\n" + 
                    "Press 3 to list the players by last name:" + "\n" + "Insert your choice...: ");
                {
                    switch (userValue)
                    {
                        case '1':
                            Console.WriteLine("Hello");
                            break;
                    }
                    break;
                }

7 个答案:

答案 0 :(得分:1)

switch语句本身应该没问题。

问题在于变量userValue。您只评估var userValue = Console.ReadKey().KeyChar;一次,因此该值设置为该一个键值。

例如,在您的示例中,外部switch语句输入case'2',因为这是userValue设置的内容。但是,当输入内部switch语句时,它使用相同的值AGAIN,因为ReadKey()函数不会再次计算。 那么你的switch语句会将“userValue”视为2,甚至根本没有期待或等待任何输入,所以它就会掉出开关。

在这里编辑: 你可以再次调用ReadKey()函数来解决这个问题,或者使用第二个变量:

//Inner switch statement:
//{ (bracket is redundant)
    userValue = Console.ReadKey().KeyChar;
    switch (userValue)
    {
        // switch body here...
    }
//}

答案 1 :(得分:0)

您的代码中有两件事

第一

如果您的开关值与代码中的开关值相同,则无法工作,因为一个变量只能有一个值。

第二

删除括号

case '2':
                Console.WriteLine("\n" + "You have entered women's single");
                Console.Write("Press 1 to start the tournament:" + "\n" + "Press 2 to list the players by first name:" + "\n" + 
                    "Press 3 to list the players by last name:" + "\n" + "Insert your choice...: ");
                //{          <- remove
                    switch (userValue)
                    {
                        case '1':
                            Console.WriteLine("Hello");
                            break;
                    }
                    break;
                //}          <- remove

答案 2 :(得分:0)

在我看来,那里有一个额外的花括号?不是吗?不应该是:

  case '2':
            Console.WriteLine("\n" + "You have entered women's single");
            Console.Write("Press 1 to start the tournament:" + "\n" + "Press 2 to list the players by first name:" + "\n" + 
                "Press 3 to list the players by last name:" + "\n" + "Insert your choice...: ");
             switch (userValue)
             {
                 case '1':
                     Console.WriteLine("Hello");
                     break;
                 default
                     return false;
             }
             break;

答案 3 :(得分:0)

您需要先重新读取该值。

case '2':
    Console.WriteLine("\n" + "You have entered women's single");
    Console.Write("Press 1 to start the tournament:" + "\n" + "Press 2 to list the players by first name:" + "\n" +
        "Press 3 to list the players by last name:" + "\n" + "Insert your choice...: ");
    userValue = Console.ReadKey().KeyChar;
    {
        switch (userValue)
        {
            case '1':
                Console.WriteLine("Hello");
                break;
        }
    }
    break;

答案 4 :(得分:0)

除了损害可读性之外,将switch嵌套在另一个switch内也没问题。该语言完全支持它。

在你的情况下你的switch不起作用,因为你打开一个自进入外部开关后没有改变的变量,所以这个结构实际上没用。在输入嵌套开关之前添加代码以修改userValue,如下所示:

case '2':
    Console.WriteLine("\n" + "You have entered women's single");
    Console.Write("Press 1 to start the tournament:" + "\n" + "Press 2 to list the players by first name:" + "\n" + 
        "Press 3 to list the players by last name:" + "\n" + "Insert your choice...: ");
    var userChoice = Console.ReadKey().KeyChar; // <<<<<==== Add this line
    switch (userChoice) {
        case '1':
            Console.WriteLine("Hello");
            break;
    }
    break;

答案 5 :(得分:0)

切换开关应该可以正常工作!

int x = 1;

    switch(x)
    {
        case 1: // Enters Here cause x = 1
            Console.WriteLine("test"); //prints
            switch(x) // x still = 1
            {
                case 1: //enters here cause x = 1
                Console.WriteLine("works"); //prints
                break;
            }
            break;
        default:
            Console.WriteLine("doesnt work");
            break;
    }

(输出将是:&#34;测试&#34;&#34;工作&#34;)

你恰好写得很奇怪&#34; {}&#34;,那是问题吗?

如果要输入不同的Switch案例,则必须更改开关(值)的值以输入不同的情况。

在你的情况下:

case '2':
            Console.WriteLine("\n" + "You have entered women's single");
            Console.Write("Press 1 to start the tournament:" + "\n" + "Press 2 to list the players by first name:" + "\n" + 
                "Press 3 to list the players by last name:" + "\n" + "Insert your choice...: ");
            //Ask for a new input here = (NEWVALUE)
            switch (NEWVALUE)
            {
                case '1':
                Console.WriteLine("Hello");
                break;
            }
            break;

答案 6 :(得分:0)

首先,您不需要嵌套开关。你必须连续选择两件事:

  1. 锦标赛类型
  2. 所选锦标赛类型的操作
  3. 因此,您可以为锦标赛类型创建枚举:

    public enum TournamentType
    {
        Default,
        SingleWomen,
        SingleMen,
        DoubleWomen,
        DoubleMen,
        DoubleMix
    }
    

    然后你需要选择选项。您可以在此处使用switch语句,但您也可以创建选项选择器类:

    public class OptionSelector<T>
    {
        private readonly List<Option> options = new List<Option>();
        public T SelectedOption { get; private set; }
    
        public OptionSelector<T> WithOption(T value, string title)
        {
            options.Add(new Option { Value = value, Title = title });
            return this;
        }
    
        public bool SelectOption()
        {
            if (!options.Any()) return true;            
    
            Console.WriteLine($"Choose one of the {options.Count} options:");    
            for(int i = 0; i < options.Count; i++)
                Console.WriteLine($" {i + 1} - {options[i].Title}");
    
            Console.Write("Your choice: ");
            var key = Console.ReadKey().KeyChar;
            Console.WriteLine();    
            int choice = key - '0';
            if (!Char.IsDigit(key) || choice == 0 || options.Count < choice) {
                Console.WriteLine($"Sorry, only digits 1..{options.Count} are allowed");
                return false;
            }
    
            SelectedOption = options[choice - 1].Value;
            return true;
        }
    
        private class Option {
            public T Value { get; set; }
            public string Title { get; set; }
        }
    }
    

    几行代码,但功能很好 - 这个类允许以流畅的方式构建一组选项,然后接受用户输入。如果输入有效,则可通过SelectedOption属性使用所选选项。否则将显示详细的错误消息。这里的好处是选项选择器是一个通用类。每个选项都可以是字面上的任何东西 - 整数,字符串,枚举值,甚至是方法。使用此类,您的所有代码都可以折叠为:

    Console.WriteLine($"You have now entered the 2017 Wimbledon tournament!\n");
    var tournamentTypeSelector = new OptionSelector<TournamentType>()
        .WithOption(TournamentType.Default, "Default tournament")
        .WithOption(TournamentType.SingleWomen, "Women's single")
        .WithOption(TournamentType.SingleMen, "Men's single")
        .WithOption(TournamentType.DoubleWomen, "Women's double")
        .WithOption(TournamentType.DoubleMix, "Mix double");
    
    while (!tournamentTypeSelector.SelectOption()) { /*Console.Clear();*/ }
    
    var tournamentType = tournamentTypeSelector.SelectedOption;
    var actionSelector = new OptionSelector<Action>()
        .WithOption(() => StartTournament(tournamentType), "Start the tournament")
        .WithOption(() => Console.WriteLine("Not implemented"), "List players by first name")
        .WithOption(() => Console.WriteLine("Not implemented"), "List players by last name");
    
    while (!actionSelector.SelectOption()) { /*Console.Clear();*/ }
    actionSelector.SelectedOption(); // invoke selected action
    

    宇呼!根本没有开关

    此处的第一个选择器选择锦标赛类型。第二个选择器选择要调用的动作。这里的好处是你可以将参数传递给那些动作(例如锦标赛类型)。 Btw StartTournament是包含相应功能的方法:

    private static void StartTournament(TournamentType tournamentType)
    {
        // your code here
        Console.WriteLine("Tournament started");
    }
    

    检查Fiddle以查看其工作原理。请注意,小提琴不支持Console.ReadKey,因此您应该每次都按Enter键。