如何避免多次重复类似的代码?

时间:2018-07-17 03:29:24

标签: c# loops console console-application do-while

我正在做一个类似控制台应用程序的Subway餐厅。它在很大程度上取决于循环,并且我已经重复了很多次特定的循环。

基本上,我编写选项,然后使光标位于初始选项上方。用户将光标悬停在Enter上的任何选项均被选中。

这是代码的第一部分(相当大,但这就是为什么我要在这里询问的原因):

static int Row = 0; //To set the row of the cursor

    static void Menu()
    {
        Console.WriteLine("Hi, welcome to Subway!"); //Line 0
        Console.WriteLine(); //Line 1

        //Bread Selection
        string[] breadOptions =
        {
                        "Hearty Italian",       //Element 0
                        "9-Grain Honey Oat",    //Element 1
                        "Jalapeno Cheese",      //Element 2
                        "Monterey Cheddar",     //Element 3
                        "Parmesan Oregano",     //Element 4
                        "Roasted Garlic",       //Element 5
                        "Rosemary & Sea Salt",  //Element 6
                        "Rye Bread",            //Element 7
                        "Gluten-Free Bread",    //Element 8
        };

        Console.WriteLine("Choose you bread!"); //Line 2
        Console.WriteLine("[ ]" + breadOptions[0]); //Line 3
        Console.WriteLine("[ ]" + breadOptions[1]); //Line 4
        Console.WriteLine("[ ]" + breadOptions[2]); //Line 5
        Console.WriteLine("[ ]" + breadOptions[3]); //Line 6
        Console.WriteLine("[ ]" + breadOptions[4]); //Line 7
        Console.WriteLine("[ ]" + breadOptions[5]); //Line 8
        Console.WriteLine("[ ]" + breadOptions[6]); //Line 9
        Console.WriteLine("[ ]" + breadOptions[7]); //Line 10
        Console.WriteLine("[ ]" + breadOptions[8]); //Line 11

        Row = 3; //set the row to the first bread option
        int currentBread = 0; //a couter to keep track of the bread
        ConsoleKeyInfo breadKey = new ConsoleKeyInfo();

        do
        {   //Loop that goes with the cursor through the menu items
            for (Row = 3; Row < breadOptions.Length + 3; Row++)
            {
                //Highlight the current bread with the cursor in the box
                if (currentBread == Row - 3)
                    Console.SetCursorPosition(1, Row);
            }

            //reads the key
            breadKey = Console.ReadKey();
            switch (breadKey.Key)
            {
                case ConsoleKey.DownArrow:
                    //if the current item is the last one in the array, reset the counter.
                    if (currentBread == breadOptions.Length - 1)
                        //-1 because currentBread follows the array, and array starts at 0
                        //but the array lengh doensn't start at 0. 0 is an empty array
                        currentBread = 0;
                    //otherwise, add one to the counter
                    else
                        currentBread++;
                    break;

                case ConsoleKey.UpArrow:
                    //if the user presses Up in the first option, it goes to the last
                    if (currentBread == 0)
                        currentBread = breadOptions.Length - 1;
                    //otherwise, remove one from the counter
                    else
                        currentBread--;
                    break;
            }

        }
        //keep looping until the user presses enter
        while (breadKey.Key != ConsoleKey.Enter);

        Console.SetCursorPosition(0, 12); //set the cursor back to the next line after the last Console.WriteLine

        //make a string to store the selected bread and make it be the selected bread
        string bread = breadOptions[currentBread];

并且,此do-while循环再次重复几次,这是另一个示例:

//Bread Size
        string[] sizeOptions = { "6-inches", "Footlong"};

        Console.WriteLine(); //Line 12
        Console.WriteLine("Choose a bread size."); //Line 13
        Console.WriteLine("[ ]" + sizeOptions[0]); //Line 14
        Console.WriteLine("[ ]" + sizeOptions[1]); //Line 15

        Row = 14;
        int currentSize = 0;
        ConsoleKeyInfo sizeKey = new ConsoleKeyInfo();

        do
        {
            for (Row = 14; Row < sizeOptions.Length + 14; Row++)
            {
                if (currentSize == Row - 14)
                    Console.SetCursorPosition(1, Row);
            }

            sizeKey = Console.ReadKey();
            switch (sizeKey.Key)
            {
                case ConsoleKey.DownArrow:
                    if (currentSize == sizeOptions.Length - 1)
                        currentSize = 0;
                    else
                        currentSize++;
                    break;
                case ConsoleKey.UpArrow:
                    if (currentSize == 0)
                        currentSize = sizeOptions.Length - 1;
                    else
                        currentSize--;
                    break;
            }
        } while (sizeKey.Key != ConsoleKey.Enter);

        Console.SetCursorPosition(0, 16);

        string size = sizeOptions[currentSize];

我想知道是否有一种方法可以在每次我需要选择一个选项时不编写此循环。

2 个答案:

答案 0 :(得分:2)

您可以使用一种方法来做到这一点:

    int GetOption(int startRow, string[] options)
    {
        int currentOption = 0;
        ConsoleKeyInfo sizeKey = new ConsoleKeyInfo();

        do
        {
            for (int i = startRow; i < options.Length + startRow; i++)
            {
                if (currentOption == i - startRow)
                    Console.SetCursorPosition(1, i);
            }

            sizeKey = Console.ReadKey();
            switch (sizeKey.Key)
            {
                case ConsoleKey.DownArrow:
                    if (currentOption == options.Length - 1)
                        currentOption = 0;
                    else
                        currentOption++;
                    break;
                case ConsoleKey.UpArrow:
                    if (currentOption == 0)
                        currentOption = options.Length - 1;
                    else
                        currentOption--;
                    break;
            }
        } while (sizeKey.Key != ConsoleKey.Enter);

        return currentOption;
    }

用法:

    string[] sizeOptions = { "6-inches", "Footlong"};
    Console.WriteLine(); //Line 12
    Console.WriteLine("Choose a bread size."); //Line 13
    Console.WriteLine("[ ]" + sizeOptions[0]); //Line 14
    Console.WriteLine("[ ]" + sizeOptions[1]); //Line 15

    Row = 14;
    int currentSize = GetOption(Row, sizeOptions);
    Console.SetCursorPosition(0, 16);
    string size = sizeOptions[currentSize];

我目前无法对其进行测试,但希望它能对您有所帮助!

答案 1 :(得分:2)

将要重用的代码块之一放入没有参数的新方法中。就像您在其中写出选项的位一样。

问自己 other 场景不想想要的那种方法是什么。在选项列表场景中,从一个地方到另一个地方不同的事物是事物的实际列表。因此,我们需要将其转换为变量(之所以命名,是因为该值可以 vary )。具体来说,如果将事物列表作为方法的参数,则可以从每个不同的地方调用该方法,并传递相关列表。

请注意,这样做可能会导致您需要解决其他问题。例如,在打印列表的位置,当前正在对要打印的每个索引进行硬编码,因此您需要找到一种更灵活的方式-列出集合中所有项目的方法,无论其中有多少个项目是。尝试查找foreach,以此作为一种方法。

将代码从一个地方移到另一个地方以使其变得更好称为重构,这是在软件开发中学习的一项非常重要的技能。我只展示了重构时发生的一种问题,但这是一个大话题。希望这会有所帮助。