Simple application to look up items in a list I'm very new to the programming world and have been working exclusively with console window applications in C# thus far. I've created a program which took me way too long to produce but I'm very proud to have completed it exactly as I set out to make it. It does what I wanted it to do, however the code is separated into many different methods. Again, being a newbie, I don't know a lot about formatting my code for readability's sake, so I'd love to have some outside opinions about what you would change, if anything, about the text so that I may be pointed in the right direction for future applications I create.

class Program
{

    public static string Name { get; set; }

    public static void Main()
    {
        Console.Write("Please Enter Your Name: ");
        Name = Console.ReadLine();
        SearchBarStart(Name);
    }

    public static void SearchBarStart(string searchName)
    {
        Console.WriteLine("Welcome, {0}", searchName);
        Thread.Sleep(1000);

        SearchChecker();

    }

    public static void SearchBar(string searchName)
    {
        Console.Clear();
        Console.WriteLine("Welcome back, {0}", searchName);
        Thread.Sleep(1000);

        SearchChecker();
    }

    public static void SearchChecker()
    {
        Item Ball = new Item() { Name = "Ball", Price = 100.001F, Popularity = 1 };
        Item Book = new Item() { Name = "Book", Price = 210.1F, Popularity = 5 };
        Item Bag = new Item() { Name = "Bag", Price = 300F, Popularity = 4 };

        List&lt;Item&gt; items = new List&lt;Item&gt;();
        items.Add(Ball);
        items.Add(Book);
        items.Add(Bag);

        string userChoice = string.Empty;

        do
        {
            Console.Write("Please enter which item would you like to view: ");
            userChoice = Console.ReadLine();

            Item resultItem = items.Find(item =&gt; item.Name == userChoice);

            if (resultItem == null)
            {
                Console.WriteLine("Item name not valid");
                SearchChecker();
            }
            else
            {
                Console.WriteLine("Item Name: {0}\n" +
                    "Item Price: {1:C}\n" +
                    "Item Popularity Hits: {2}\n",
                    resultItem.Name, resultItem.Price, resultItem.Popularity);
            }
            Console.WriteLine("Would you like to continue? (yes/no)");
            userChoice = Console.ReadLine();
        }
        while (userChoice == "yes");

        Exit();
    }

    public static void Exit()
    {
        Console.WriteLine("Are you sure? (yes/no)");
        string answer = Console.ReadLine();

        if (answer == "yes")
        {
            Console.WriteLine("Press enter again to exit");
            Console.ReadLine();
        }
        else if (answer == "no")
        {
            SearchBar(Name);
        }
        else
        {
            Console.WriteLine("Sorry, I don't recognize {0}\n", answer);
            Exit();
        }

    }
}

class Item
{
    public string Name { get; set; }
    public float Price { get; set; }
    public int Popularity { get; set; }
}
First, I'm going to show you some interesting points.

1. The callstack

You're calling some methods recursively. A recursive method calls itself. See in SearchChecker() and Exit() where those methods call themselves, eg. SearchChecker() calls SearchChecker() again and Exit() calls Exit() again.

What will happen if you call it recursively? See the callstack. The picture below shows what happens when I repeatly entering wrong items. I put a break point in the line where it prints "item name not valid". I marked the callstack in a red box. See it repeatedly calling SearchChecker(). Same thing happens in second picture when Exit() is calling itself recursively by entering wrong answer (yes/no).




2. A bug when you're trying to exit the program because of recursion

This only happens if you do what I did in number 1. Add 2 lines in the Main method so it looks like:

public static void Main()
{
    Console.Write("Please Enter Your Name: ");
    Name = Console.ReadLine();
    SearchBarStart(Name);
    Console.WriteLine("Press any key...");
    Console.ReadKey(true);
}


Try these steps:


Enter name
When asked what items you want, repeat wrong answer 2 times, eg. entering "z" 2 times
Enter a correct item in the 3rd attempt, eg. "Ball"
Program shows the item information.
When asked if you want to continue, choose "no"
When asked if you are sure, choose "yes"
You're asked to press enter again. Press enter.
Program should exit, but it asked if you would like to continue again. Do step 5 till 7 till the program exits.




This bug happens because of the callstack. Your program entry point is Main() method, so it ends when Main() reaches its last line. But the callstack is long (see pic #1 and #2) and it should exit each callstack before reaching back to Main().

Here's what I did to improve your code. I add some comments to make it clearer. The idea is to make each method only do a specific task. SeachCheckerStart() is the main loop for asking items, SearchChecker() is for asking and displaying item, getUserItem() is for retrieving item, printItem() is for printing item info, getChoices() is for getting choice from user, getContinue() and getConfirmExit() are for asking if user wants to continue and confirm if they want to exit.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;

class Program
{
    public static string Name { get; set; }

    public static void Main()
    {
        // get user name
        Console.Write("Please Enter Your Name: ");
        Name = Console.ReadLine();
        Console.WriteLine("Welcome, {0}", Name);
        Thread.Sleep(1000);

        bool userConfirmExit;
        do
        {
            SeachCheckerStart();

            userConfirmExit = getConfirmExit(); // get user confirmation to exit
            if (!userConfirmExit)
            {
                Console.WriteLine("Welcome back, {0}", Name);
                Thread.Sleep(1000);
            }
        } while (!userConfirmExit); // repeat what's inside this until user confirmed that they want to end the program

        Console.WriteLine("Press enter again to exit");
        Console.ReadLine();

        Console.WriteLine("Press any key...");
        Console.ReadKey(true);
    }

    public static void SeachCheckerStart()
    {
        bool userContinue;
        do
        {
            SearchChecker(); // start search
            userContinue = getContinue(); // ask if user wants to continue
        } while (userContinue); // repeat this process as long as user chooses "yes"
    }

    public static void SearchChecker()
    {
        Item item = null;
        do
        {
            item = getUserItem(); // get item from user, return null if item is not valid
        } while (item == null); // repeat until user asks a valid item

        printItem(item); // show item info
    }

    public static Item getUserItem()
    {
        var items = new List&lt;Item&gt; // initialize the List&lt;Item&gt;
        {
            new Item { Name = "Ball", Price = 100.001F, Popularity = 1 },
            new Item { Name = "Book", Price = 210.1F, Popularity = 5 },
            new Item { Name = "Bag", Price = 300F, Popularity = 4 }
        };

        Console.Write("Please enter which item would you like to view: ");
        string userItemChoice = string.Empty;
        userItemChoice = Console.ReadLine();
        var item = items.Find(i =&gt; i.Name == userItemChoice);
        if (item == null)
        {
            Console.WriteLine("Item name not valid");
        }
        return item;
    }

    public static void printItem(Item item)
    {
        Console.WriteLine("Item Name: {0}\n" +
                "Item Price: {1:C}\n" +
                "Item Popularity Hits: {2}\n",
                item.Name, item.Price, item.Popularity);
    }

    public static string getChoices(string message, params string[] choices)
    {
        string choice = null;
        do
        {
            Console.WriteLine(message);
            choice = Console.ReadLine().ToLower();
            if (!choices.Contains(choice)) // if choice is not in choices
            {
                Console.WriteLine("Sorry, I don't recognize {0}\n", choice);
            }
        } while (!choices.Contains(choice)); // repeat if choice is not in choices
        return choice;
    }

    public static bool getContinue()
    {
        var choice = getChoices("Would you like to continue? (yes/no)", "yes", "no"); // ask if user wants to continue
        if (choice == "yes")
            return true; // return true if user wants to continue
        else
            return false; // return false if user does not want to continue
    }

    public static bool getConfirmExit()
    {
        var choice = getChoices("Are you sure? (yes/no)", "yes", "no"); // get confirmation if user wants to exit
        if (choice == "yes")
            return true; // return true if user confirms that they want to exit
        else
            return false; // return false if user does not confirms that they want to exit
    }
}

class Item
{
    public string Name { get; set; }
    public float Price { get; set; }
    public int Popularity { get; set; }
}


This time the callstack is clean. See the red box in these 2 pics.



The bug in #2 won't happen because the callstack is clean.