Building a Menu-Driven Console Application in C# (2025)

This article explores how a beginner-friendly console application is developed using C# and the .NET Framework 4.8. We delve into the intricacies of creating a menu-driven interface that offers choices such as "Eat Candy," "Go Fishing," and "Play Basketball," culminating in an option to exit the application gracefully. Through a step-by-step walkthrough, we illustrate the process of writing clean, concise code while emphasizing best practices in user interaction.

Building a Menu-Driven Console Application in C# (1)
Figure 1.A screenshot of the console application displaying a menu of choices.

  • Introduction
    • Prerequisites
    • Walkthrough
      • Step 1: Creating a New Console Application Project
      • Step 2: Adding Enum Definitions
      • What is an enum?
      • Why are we using an enum?
      • Step 3: Writing the Application Logic
      • Entire Program.cs File
      • Step 4: Running the Application
  • Conclusion

This tutorial will create a simple console application using C# and the .NET Framework 4.8. Our application will display a menu of choices to the user, allowing them to perform various actions. We'll implement features such as displaying the menu, handling user input, and confirming actions like exiting the application.

This tip/trick is aimed at beginners and those just beginning to do C# programming language exercises, such as first-year computer science students. Such a problem is frequently given to those learning to program for the first time.

NOTE:I am aware of the existence of C# 12 and .NET Core 8. However, as a personal preference, I believe that using older frameworks has more instructional value. I am specifically choosing to use .NET Framework 4.8 and C# 7 to show students programming concepts such asnamespaces, etc., that must be more explicitly declared in older versions of C#. Furthermore, as this is not a very advanced tutorial, we can forego using a powerhouse such as .NET Core 8 when .NET Framework on Windows will do just fine, for my purposes.

Prerequisites

  • Visual Studio 2022 is installed on your machine.
  • Basic understanding of C# programming concepts.

Walkthrough

Step 1: Creating a New Console Application Project

  1. Open Visual Studio 2022.
  2. Click theFilemenu, point toNew, and clickProject/Solution.
  3. In the Create a new projectwindow, search for Console App (.NET Framework)".
  4. Choose the Console App (.NET Framework)template and clickNext.
  5. Name your project MenuDemoand choose a location to save it.
  6. Click Createto create the project.

Step 2: Adding Enum Definitions

  1. Inside the MenuDemo project, add a new C# file named Enums.cs.

  2. Define an enum named MenuChoices to represent the menu options. Include options for EatCandy, GoFishing, PlayBasketball, and Exit. Use the Description attribute to provide human-readable descriptions for each option.

C#

using System.ComponentModel;namespace MenuDemo{ public enum MenuChoices { [Description("Eat Candy")] EatCandy, [Description("Go Fishing")] GoFishing, [Description("Play Basketball")] PlayBasketball, [Description("Exit")] Exit }}

Listing 1.The definition of the MenuChoices enumeration.

What is an enum?

In C#, an enum (short for "enumeration") is a special data type used to define a set of named integral constants. These constants represent a finite list of possible values that a variable of that enum type can hold. Each constant in an enum has an associated integer value, which by default starts from 0 and increments by 1 for each subsequent constant.

Why are we using an enum?

In our MenuDemo application, we're using a enum called MenuChoices to represent the different options available in our menu. Instead of using raw integer values to represent each choice (e.g., 0 for "Eat Candy", 1 for "Go Fishing", and so on), we use descriptive names like EatCandy, GoFishing, etc., making our code more readable and self-explanatory.

Here are some benefits of using an enum:

  1. Readability: Using descriptive names improves code readability. When someone reads MenuChoices.EatCandy, they immediately understand the intended meaning.

  2. Type Safety: Enums provide type safety, meaning you can't assign arbitrary values to an enum variable. You're restricted to the predefined set of constants.

  3. Intellisense Support: IDEs like Visual Studio provide IntelliSense support for enums, making selecting the correct value from a list of options easier.

  4. Compile-Time Checks: The compiler performs checks to ensure that enum values are used correctly, reducing the likelihood of errors at runtime.

In summary, enums are a convenient way to define a set of related constants with meaningful names, improving code readability, maintainability, and reliability. They are particularly useful in scenarios where you have a fixed set of options or states, such as menus, application states, days of the week, etc.

Step 3: Writing the Application Logic

  1. Open Solution Explorer.

    • To do so, click theViewmenu and then clickSolution Explorer.

  2. Expand all the items in Solution Explorer, find the Program.cs file, and double-click on it.

    • The Program.cs file is now open in the Editor.

  3. Somewhere in the Program class, after the Main method, add code to define the GetUserChoicemethod.

    • This method reads user input from the console.
    • It parses the input into a MenuChoices enumeration value.
    • The corresponding value is returned if the input matches any of the enumeration values.
    • If the input cannot be parsed into a valid enumeration value, it returns MenuChoices.Unknown.
    • Here's a listing of myGetUserChoice method:
      ///<summary>///Readsuserinputfromtheconsoleandparsesitintoa///<seecref="T:MenuDemo.MenuChoices"/>enumerationvalue.///</summary>///<returns>///The<seecref="T:MenuDemo.MenuChoices"/>enumerationvaluecorrespondingto///theuserinput.///Iftheinputcannotbeparsedintoavalidenumerationvalue,returns///<seecref="F:MenuDemo.MenuChoices.Unknown"/>.///</returns>///<remarks>///Thismethodreadsalineoftextfromtheconsoleinputandattemptstoparse///itintoa<seecref="T:MenuDemo.MenuChoices"/>enumerationvalue.///<para/>///Iftheinputmatchesanyoftheenumerationvalues,thecorresponding///enumerationvalueisreturned.///<para/>///Iftheinputcannotbeparsedintoavalidenumerationvalue,themethod///returns<seecref="F:MenuDemo.MenuChoices.Unknown"/>.///</remarks>privatestaticMenuChoicesGetUserChoice(){varinput=Console.ReadLine();returnEnum.TryParse(input,outMenuChoiceschoice)?choice:MenuChoices.Unknown;}
      Listing 2.The code of theGetUserChoice method.
  4. Now, add code for the definition of the GetEnumDescription method:

    • If available, this method retrieves the description associated with a given enum value. If no Description attribute is found, it returns the string representation of the enum value.
    • It first gets the field information of the enum value using reflection.
    • It then retrieves the DescriptionAttribute associated with the enum value, if any, using the GetCustomAttribute method.
    • If a DescriptionAttribute is found, it returns the description value associated with it.
    • If no DescriptionAttribute is found, it returns the string representation of the enum value itself.
    • Here's an example listing of my implementation of GetEnumDescription:

      C#

      ///<summary>///Retrievesthedescriptionattributevalueassociatedwiththespecifiedenum///value.///</summary>///<paramname="value">///The<seelangword="enum"/>valueforwhichtoretrievethe///description.///</param>///<returns>///Thedescriptionassociatedwiththe<seelangword="enum"/>value,if///available;otherwise,the///stringrepresentationofthe<seelangword="enum"/>value.///</returns>///<remarks>///Thismethodretrievesthedescriptionattributevalue,ifpresent,associated///withthespecified<seelangword="enum"/>value.///<para/>///Ifnodescriptionattributeisfound,itreturnsthestringrepresentationof///the<seelangword="enum"/>value.///</remarks>privatestaticstringGetEnumDescription(Enumvalue){varfield=value.GetType().GetField(value.ToString());varattribute=(DescriptionAttribute)Attribute.GetCustomAttribute(field,typeof(DescriptionAttribute));returnattribute==null?value.ToString():attribute.Description;}
      Listing 3.The code of theGetEnumDescription method.

      Purpose of the Method:

    • This method is used to provide human-readable descriptions for enum values.
    • It's particularly useful when displaying enum values in a user interface or logging messages.
    • By decorating enum values with DescriptionAttribute, developers can provide meaningful descriptions that enhance the readability of the code.
  5. Define the DisplayMenu method:

    • This method displays the user's menu of choices. Each option is known as acommand.
    • It iterates through all the available menu choices, excluding Unknown, and displaying them along with their corresponding numbers.
    • It prompts the user to enter their selection.
    • Here's a listing of my version of theDisplayMenumethod:

      C#

      ///<summary>///Displaysthemenuofchoicesontheconsole.///</summary>///<remarks>///Thismethoditeratesthroughalltheavailablemenuchoicesanddisplaysthem///alongwiththeircorrespondingnumbers.///<para/>///Thenumberingofthechoicesstartsfrom<c>1</c>.///</remarks>privatestaticvoidDisplayMenu(){Console.WriteLine("Pleasechooseanaction:\n");varmenuItemNumber=1;foreach(MenuChoiceschoiceinEnum.GetValues(typeof(MenuChoices)))if(choice!=MenuChoices.Unknown){vardescription=GetEnumDescription(choice);Console.WriteLine($"[{menuItemNumber}]:{description}");menuItemNumber++;} Console.Write("\nEnteryourselection:");}
      Listing 4.The code of theDisplayMenu method.

      Purpose of the Method

    • This method is called within the Main method to display the menu of choices to the user.
    • It enhances the user experience by providing a clear and organized presentation of available options.
    • Presenting the choices in a numbered format helps the user easily identify and select their desired option.
    • The menuItemNumber variable is used to display the menu item number next to each choice.
    • It starts from 1 to represent the first menu choice. Normally, the integer(s) associated with the member(s) of an enum start from zero. Starting from 1 is a better user experience.
    • After displaying each menu choice, menuItemNumber++ incrementsmenuItemNumber by 1 to move to the next menu item.
    • This ensures that each menu choice is displayed with a unique and sequential number, starting from 1, making it easier for the user to find and select their desired option.
  6. Define the Main Method:

    • This is the entry point of the application.
    • It contains the main application logic, including displaying the menu, getting the user's choice, and performing actions based on that choice.
    • It runs in an infinite loop until the user chooses to exit the application.
    • If the user chooses Exit, it prompts them to confirm if they are sure they want to exit. After typing their response, the user must press the ENTER key on the keyboard to confirm.
      • If the confirmation is affirmative (Y or y), the application terminates.
      • If the user typesany other input, the console is cleared, and the menu is displayed again.
        • This is an important cybersecurity vulnerability mitigation: doing this guards against a so-called code injection attack.
    • After each action, it prompts the user to press any key to continue, clears the console, and displays the menu again.
    • Here's a listing of my version of the Main method:

      C#

      ///<summary>///Theentrypointoftheapplication.///</summary>///<remarks>///Thismethodservesasthestartingpointoftheconsoleapplication.///<para/>///Itcontinuouslydisplaysamenuofchoicestotheuserandexecutesthe///correspondingactionsbasedontheirselection.///<para/>///Themenuisdisplayeduntiltheuserdecidestoexittheapplication.///</remarks>publicstaticvoidMain(){while(true){DisplayMenu();varchoice=GetUserChoice(); //Convert1-basedmenuchoiceto0-basedindexvarchoiceIndex=(int)choice-1; //Checkifchoiceiswithinthevalidrangeif(choiceIndex>=0&&choiceIndex<Enum.GetValues(typeof(MenuChoices)).Length)//Checkagainstallmenuitems//Performactionbasedonuserchoiceindexswitch(choiceIndex){case(int)MenuChoices.EatCandy:Console.WriteLine("YouchosetoEatCandy."); //AddyourEatCandylogicherebreak; case(int)MenuChoices.GoFishing:Console.WriteLine("YouchosetoGoFishing."); //AddyourGoFishinglogicherebreak; case(int)MenuChoices.PlayBasketball:Console.WriteLine("YouchosetoPlayBasketball."); //AddyourPlayBasketballlogicherebreak; case(int)MenuChoices.Exit:Console.Write("Areyousureyouwanttoexittheapplication?(Y/N):");varconfirmation=Console.ReadLine().ToUpper()[0];Console.WriteLine();if(confirmation=='Y'){Console.WriteLine("Exitingtheapplication...");return;//ExittheMainmethod} Console.Clear();continue; default:Console.WriteLine("Invalidchoice.Pleasetryagain.");break;}elseConsole.WriteLine("Invalidchoice.Pleasetryagain."); Console.WriteLine("Pressanykeytocontinue...");Console.ReadKey();Console.Clear();//Cleartheconsoleforthenextiteration}}
      Listing 5.The definition of the Main method.

      Purpose of the Method

    • The Main method serves as the entry point of a C# console application.
    • When the application is executed, the operating system looks for the Main method to start the program.
    • All the code inside the Main method is executed when the application starts.
    • It is where the execution of the program begins.
    • The Main method contains the main logic of the application.
    • It typically includes tasks such as displaying user interfaces, processing user input, and performing various actions based on user choices.
    • The Main method often involves control flow structures such as loops (while, for, foreach) and conditional statements (if, else, switch) to control the flow of execution within the application.
    • The Main method is responsible for determining when the application should terminate.
    • It usually runs in a loop until a specific condition is met, such as the user choosing to exit the application or a certain task being completed.
    • The Main method may also handle resource management tasks such as opening and closing files, database connections, or network connections.
    • Error handling code, such as try-catch blocks, may also be included in the Main method to handle exceptions that occur during the execution of the application.

Entire Program.cs File

Here's the entire Program.cs file with all the methods combined:

C#

usingSystem;usingSystem.ComponentModel; namespaceMenuDemo{///<summary>///Definesthebehavioroftheapplication.///</summary>publicstaticclassProgram{///<summary>///Theentrypointoftheapplication.///</summary>///<remarks>///Thismethodservesasthestartingpointoftheconsoleapplication.///<para/>///Itcontinuouslydisplaysamenuofchoicestotheuserandexecutesthe///correspondingactionsbasedontheirselection.///<para/>///Themenuisdisplayeduntiltheuserdecidestoexittheapplication.///</remarks>publicstaticvoidMain(){while(true){DisplayMenu();varchoice=GetUserChoice(); //Convert1-basedmenuchoiceto0-basedindexvarchoiceIndex=(int)choice-1; //Checkifchoiceiswithinthevalidrangeif(choiceIndex>=0&&choiceIndex<Enum.GetValues(typeof(MenuChoices)).Length)//Checkagainstallmenuitems//Performactionbasedonuserchoiceindexswitch(choiceIndex){case(int)MenuChoices.EatCandy:Console.WriteLine("YouchosetoEatCandy."); //AddyourEatCandylogicherebreak; case(int)MenuChoices.GoFishing:Console.WriteLine("YouchosetoGoFishing."); //AddyourGoFishinglogicherebreak; case(int)MenuChoices.PlayBasketball:Console.WriteLine("YouchosetoPlayBasketball."); //AddyourPlayBasketballlogicherebreak; case(int)MenuChoices.Exit:Console.Write("Areyousureyouwanttoexittheapplication?(Y/N):");varconfirmation=Console.ReadLine().ToUpper()[0];Console.WriteLine();if(confirmation=='Y'){Console.WriteLine("Exitingtheapplication...");return;//ExittheMainmethod} Console.Clear();continue; default:Console.WriteLine("Invalidchoice.Pleasetryagain.");break;}elseConsole.WriteLine("Invalidchoice.Pleasetryagain."); Console.WriteLine("Pressanykeytocontinue...");Console.ReadKey();Console.Clear();//Cleartheconsoleforthenextiteration}} ///<summary>///Displaysthemenuofchoicesontheconsole.///</summary>///<remarks>///Thismethoditeratesthroughalltheavailablemenuchoicesanddisplaysthem///alongwiththeircorrespondingnumbers.///<para/>///Thenumberingofthechoicesstartsfrom<c>1</c>.///</remarks>privatestaticvoidDisplayMenu(){Console.WriteLine("Pleasechooseanaction:\n");varmenuItemNumber=1;foreach(MenuChoiceschoiceinEnum.GetValues(typeof(MenuChoices)))if(choice!=MenuChoices.Unknown){vardescription=GetEnumDescription(choice);Console.WriteLine($"[{menuItemNumber}]:{description}");menuItemNumber++;} Console.Write("\nEnteryourselection:");} ///<summary>///Retrievesthedescriptionattributevalueassociatedwiththespecifiedenum///value.///</summary>///<paramname="value">///The<seelangword="enum"/>valueforwhichtoretrievethe///description.///</param>///<returns>///Thedescriptionassociatedwiththe<seelangword="enum"/>value,if///available;otherwise,the///stringrepresentationofthe<seelangword="enum"/>value.///</returns>///<remarks>///Thismethodretrievesthedescriptionattributevalue,ifpresent,associated///withthespecified<seelangword="enum"/>value.///<para/>///Ifnodescriptionattributeisfound,itreturnsthestringrepresentationof///the<seelangword="enum"/>value.///</remarks>privatestaticstringGetEnumDescription(Enumvalue){varfield=value.GetType().GetField(value.ToString());varattribute=(DescriptionAttribute)Attribute.GetCustomAttribute(field,typeof(DescriptionAttribute));returnattribute==null?value.ToString():attribute.Description;} ///<summary>///Readsuserinputfromtheconsoleandparsesitintoa///<seecref="T:MenuDemo.MenuChoices"/>enumerationvalue.///</summary>///<returns>///The<seecref="T:MenuDemo.MenuChoices"/>enumerationvaluecorrespondingto///theuserinput.///Iftheinputcannotbeparsedintoavalidenumerationvalue,returns///<seecref="F:MenuDemo.MenuChoices.Unknown"/>.///</returns>///<remarks>///Thismethodreadsalineoftextfromtheconsoleinputandattemptstoparse///itintoa<seecref="T:MenuDemo.MenuChoices"/>enumerationvalue.///<para/>///Iftheinputmatchesanyoftheenumerationvalues,thecorresponding///enumerationvalueisreturned.///<para/>///Iftheinputcannotbeparsedintoavalidenumerationvalue,themethod///returns<seecref="F:MenuDemo.MenuChoices.Unknown"/>.///</remarks>privatestaticMenuChoicesGetUserChoice(){varinput=Console.ReadLine();returnEnum.TryParse(input,outMenuChoiceschoice)?choice:MenuChoices.Unknown;}}}

Listing 6.The final content of our Program.cs file.

Step 4: Running the Application

  1. Press F5on the keyboard, or click the Debugmenu on the menu bar, and then clickStart Debuggingto run the application.
    • Visual Studio should automatically build your application into a .exe file, and then launch that .exe file for you.
    • What you see should resemble -- although it may not look exactly the same --Figure 1.
  2. Follow the on-screen instructions to interact with the menu.
  3. Test each menu option and verify that the application behaves as expected.

Congratulations! You've successfully created a menu-driven console application in C# using .NET Framework 4.8. You've learned to display a menu, handle user input, and implement features like confirming actions before execution. Keep exploring and experimenting with C# to enhance your programming skills further.

Dr. Brian Hart obtained his Ph.D. in Astrophysics from the University of California, Irvine, in 2008. Under Professor David Buote, Dr. Hart researched the structure and evolution of the universe. Dr. Hart is an Astrodynamicist / Space Data Scientist with Point Solutions Group in Colorado Springs, CO, supporting Space Operations Command, United States Space Force. Dr. Hart is a Veteran of the U.S. Army and the U.S. Navy, having most recently served at Fort George G. Meade, MD, as a Naval Officer with a Cyber Warfare Engineer designator. Dr. Hart has previously held positions at Jacobs Engineering supporting Cheyenne Mountain/Space Force supporting tests, with USSPACECOM/J58 supporting operators using predictive AI/ML with Rhombus Power, and with SAIC supporting the Horizon 2 program at STARCOM. Dr. Hart is well known to the community for his over 150 technical publications and public speaking events. Originally from Minneapolis/Saint Paul, Minnesota, Dr. Hart lives in Colorado Springs with his Black Lab, Bruce, and likes bowling, winter sports, exploring, and swimming. Dr. Hart has a new movie coming out soon, a documentary called "Galaxy Clusters: Giants of the Universe," about his outer space research. The movie showcases the Chandra X-ray Observatory, one of NASA’s four great observatories and the world’s most powerful telescopes for detecting X-rays. The movie has been accepted for screening at the U.S. Air Force Academy ("USAFA" for short) Planetarium and will highlight how scientists use clusters of galaxies, the largest bound objects in the Universe, to learn more about the formation and evolution of the cosmos --- as well as the space telescopes used for this purpose, and the stories of the astronauts who launched them and the scientists who went before Dr. Hart in learning more about the nature of the Universe.

Building a Menu-Driven Console Application in C# (2025)
Top Articles
Latest Posts
Recommended Articles
Article information

Author: Gov. Deandrea McKenzie

Last Updated:

Views: 6114

Rating: 4.6 / 5 (66 voted)

Reviews: 81% of readers found this page helpful

Author information

Name: Gov. Deandrea McKenzie

Birthday: 2001-01-17

Address: Suite 769 2454 Marsha Coves, Debbieton, MS 95002

Phone: +813077629322

Job: Real-Estate Executive

Hobby: Archery, Metal detecting, Kitesurfing, Genealogy, Kitesurfing, Calligraphy, Roller skating

Introduction: My name is Gov. Deandrea McKenzie, I am a spotless, clean, glamorous, sparkling, adventurous, nice, brainy person who loves writing and wants to share my knowledge and understanding with you.