Using a Switch statement with Enum C#

20,497

Solution 1

NET Framework contains a huge amount of code. Sometime it is just difficult to find the needed one, but the probability that there is something already there are high. And, while it takes time to search, it is a well spent time because you feed yourself with useful knowledge for your future work

CultureInfo.CurrentCulture.DayFormatInfo.MonthNames
DateTime.DaysInMonth

using System.Globalization;
static void Main(string[] args)
{
    Console.Write("Enter a Number to find out what Month it is: ");

    int userInput = Convert.ToInt16(Console.ReadLine());
    if(userInput > 0 && userInput < 13)
    {            
         string monthName = CultureInfo.CurrentCulture.DayTimeFormat.MonthNames[userInput-1];
         int daysInMonth = DateTime.DaysInMonth(2013, userInput);
         ......

    }
}

If you need to account also for leap years you should get input for the year but it is pretty straightforward

Solution 2

That's because your enum has it all mixed up.

There are repetitive values for 31 and 30.

Here is a working example (However there are more ways of optimising it. Like using DateTime class)

public enum Months : int
{
    None = 0,
    January = 1,
    February = 2,
    March = 3,
    April = 4,
    May = 5,
    June = 6,
    July = 7,
    August = 8,
    September = 9,
    October = 10,
    November = 11,
    December = 12
};

public class Program
{
    public const string NEWLINE = "\n";     //constant for new line

    static void Main(string[] args)
    {
        try
        {
            //prompt user for month number.
            Console.Write("Enter a Number to find out what Month it is: ");

            //convert users answer to integer
            int userInput = Convert.ToInt16(Console.ReadLine());

            //declare and initalise
            int daysInMonth = 0;
            Months answer;

            //call relevent calculation methods
            answer = DetermineMonth(userInput);

            if (answer == Months.None) 
            {
                Console.WriteLine("Please enter a value between 1 and 12");
                return;
            }

            daysInMonth = DetermineDaysInMonth(answer);

            //Write users answer to screen
            Console.WriteLine(answer);

            //Prompt user, whether they want to know number of days in the
            //month
            Console.Write("Would you like to know the number of days in {0}: ", answer);

            //assign users answer to variable
            string userAnswer = Console.ReadLine();

            //Output answer if needed.
            if (userAnswer == "yes".Trim().ToLower())
            {
                Console.WriteLine("The number of days in {0} is: {1}", answer, daysInMonth.ToString());
            }
            else if (userAnswer == "no".Trim().ToLower())
            {
                Console.WriteLine(NEWLINE);
                Console.WriteLine("You answered No, Have a good day!");
            }
            else
                Console.WriteLine("Please answer yes or no.");

            Console.ReadLine(); //Pauses screen for user
        }
        //catch any errors.
        catch (Exception err)
        {
            Console.WriteLine("Error" + err.Message);
        }
    }

    /// <summary>
    /// Determines What month the use enters and returns string value
    /// </summary>
    /// <param name="userInput"></param>
    /// <returns>returns the month as string</returns>
    public static Months DetermineMonth(int userInput)
    {
        switch (userInput)
        {
            case 1:
                return Months.January;
            case 2:
                return Months.February;
            case 3:
                return Months.March;
            case 4:
                return Months.April;
            case 5:
                return Months.May;
            case 6:
                return Months.June;
            case 7:
                return Months.July;
            case 8:
                return Months.August;
            case 9:
                return Months.September;
            case 10:
                return Months.October;
            case 11:
                return Months.November;
            case 12:
                return Months.December;
        }
        return Months.None;
    }

    /// <summary>
    /// Determines how many days is in selected month as integer
    /// </summary>
    /// <param name="userInput"></param>
    /// <returns>returns how many days in month</returns>
    public static int DetermineDaysInMonth(Months userInput)
    {
        switch (Convert.ToInt32(userInput))
        {
            case 1:
            case 3:
            case 5:
            case 7:
            case 8:
            case 10:
            case 12:
                return 31;
            case 2:
                return 28;
            case 4:
            case 6:
            case 9:
            case 11:
                return 30;
        }
        return 0;
    }
}

Solution 3

You use an enum to create symbolic names for constants. That's not what you want in this case.

I think what you want is a lookup table that, given a value A, returns a value B. In your case, you can use a couple of arrays:

string[] monthNames = new string[]
{
    "January", "February", "March", "April", "May", "June",
    "July", "August", "September", "November", "December"
};
int[] monthDays = new int[] {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

And you can then get a month name and the number of days with a lookup:

int userInput = Convert.ToInt16(Console.ReadLine());
if (userInput < 1 || userInput > 12)
    Console.WriteLine("Error: invalid month.");
else
{
    answer = monthNames[userInput-1];
    daysInMonth = monthDays[userInput-1];
}

There are other ways to do this, including using structs or classes for the months and days, but those are slightly more advanced topics.

In addition, .NET has a DateTime structure that has all these capabilities and more for working with dates and times. In a production program, you'd use that rather than rolling your own.

Share:
20,497
Todd Johnson
Author by

Todd Johnson

Updated on July 21, 2020

Comments

  • Todd Johnson
    Todd Johnson almost 4 years

    Hi I am creating a Console app, where the user enters a number of a month and the app works out what month it is and displays answer and displays number of days in the month. I had it working when the switch statements was in the Main method, however now it displays the wrong month. I have the following code:

    namespace ConsoleCA2{
    
    public enum Months
    {
        January = 31,
        February = 28,
        March = 31,
        April = 30,
        May = 31,
        June = 30,
        July = 31,
        August = 31,
        September = 30,
        October = 31,
        November = 30,
        December = 31
    };
    
    public class Program
    {
        public const string NEWLINE = "\n";     //constant for new line
    
    
        static void Main(string[] args)
        {
            try
            {
    
                //prompt user for month number.
                Console.Write("Enter a Number to find out what Month it is: ");
    
                //convert users answer to integer
                int userInput = Convert.ToInt16(Console.ReadLine());
    
                //declare and initalise
                int daysInMonth = 0;
                string answer = String.Empty;
    
                //call relevent calculation methods
                answer = DetermineMonth(userInput);
                daysInMonth = DetermineDaysInMonth(userInput);
    
                //Write users answer to screen
                Console.WriteLine(answer);
    
                //Prompt user, whether they want to know number of days in the
                //month
                Console.Write("Would you like to know the number of days in" +
                    " {0}: ", answer);
    
                //assign users answer to variable
                string userAnswer = Console.ReadLine();
    
                    //Output answer if needed.
                    if (userAnswer == "yes".Trim().ToLower())
                    {
                        Console.WriteLine("The number of days in {0} is: {1}", 
                            answer, daysInMonth.ToString());
                    }
                    else if (userAnswer == "no".Trim().ToLower())
                    {
                        Console.WriteLine(NEWLINE);
                        Console.WriteLine("You answered No, Have a good day!");
                    }
                    else
                    {
                        Console.WriteLine("Please answer yes or no.");
                    }
    
                Console.Read(); //Pauses screen for user
            }
                //catch any errors.
            catch (Exception err)
            {
                Console.WriteLine("Error" + err.Message);
            }
    
        }
    
    
        /// <summary>
        /// Determines What month the use enters and returns string value
        /// </summary>
        /// <param name="userInput"></param>
        /// <returns>returns the month as string</returns>
        public static String DetermineMonth(int userInput)
        {
            switch (userInput)
            {
                case 1:
                    return Months.January.ToString();
                case 2:
                    return Months.February.ToString();
                case 3:
                    return Months.March.ToString();
                case 4:
                    return Months.April.ToString();
                case 5:
                    return Months.May.ToString();
                case 6:
                    return Months.June.ToString();
                case 7:
                    return Months.July.ToString();
                case 8:
                    return Months.August.ToString();
                case 9:
                    return Months.September.ToString();
                case 10:
                    return Months.October.ToString();
                case 11:
                    return Months.November.ToString();
                case 12:
                    return Months.December.ToString();
                default:
                    return "Error";
            }
    
    
    
        }
    
        /// <summary>
        /// Determines how many days is in selected month as integer
        /// </summary>
        /// <param name="userInput"></param>
        /// <returns>returns how many days in month</returns>
        public static int DetermineDaysInMonth(int userInput)
        {
            switch (userInput)
            {
                case 1:
                    return Convert.ToInt16(Months.January);
                case 2:
                    return Convert.ToInt16(Months.February);
                case 3:
                    return Convert.ToInt16(Months.March);
                case 4:
                    return Convert.ToInt16(Months.April);
                case 5:
                    return Convert.ToInt16(Months.May);
                case 6:
                    return Convert.ToInt16(Months.June);
                case 7:
                    return Convert.ToInt16(Months.July);
                case 8:
                    return Convert.ToInt16(Months.August);
                case 9:
                    return Convert.ToInt16(Months.September);
                case 10:
                    return Convert.ToInt16(Months.October);
                case 11:
                    return Convert.ToInt16(Months.November);
                case 12:
                    return Convert.ToInt16(Months.December);
                default:
                    return 0;
            }
        }
    

    The old switch statement was this:

            switch (userInput)
            {
            case 1:
                answer = Months.January.ToString();
                daysInMonth = Convert.ToInt16(Months.January);
                break;
            case 2:
                answer = Months.February.ToString();
                daysInMonth = Convert.ToInt16(Months.February);
                break;
            case 3:
                answer = Months.March.ToString();
                daysInMonth = Convert.ToInt16(Months.March);
                break;
            case 4:
                answer = Months.April.ToString();
                daysInMonth = Convert.ToInt16(Months.April);
                break;
            case 5:
                answer = Months.May.ToString();
                daysInMonth = Convert.ToInt16(Months.May);
                break;
            case 6:
                answer = Months.June.ToString();
                daysInMonth = Convert.ToInt16(Months.June);
                break;
            case 7:
                answer = Months.July.ToString();
                daysInMonth = Convert.ToInt16(Months.July);
                break;
            case 8:
                answer = Months.August.ToString();
                daysInMonth = Convert.ToInt16(Months.August);
                break;
            case 9:
                answer = Months.September.ToString();
                daysInMonth = Convert.ToInt16(Months.September);
                break;
            case 10:
                answer = Months.October.ToString();
                daysInMonth = Convert.ToInt16(Months.October);
                break;
            case 11:
                answer = Months.November.ToString();
                daysInMonth = Convert.ToInt16(Months.November);
                break;
            case 12:
                answer = Months.December.ToString();
                daysInMonth = Convert.ToInt16(Months.December);
                break;
            default:
                answer = "Error";
                break;
        }
    

    Which worked until I changed to separate methods then it went downhill from there. Now even when I put it back it still gets the months mixed up?

    So confused :S

    Thank you in advance for any help... if you can understand the messy code :p