在Enum C#中使用Switch语句

时间:2013-07-20 09:18:10

标签: c# enums switch-statement

您好我正在创建一个控制台应用程序,用户输入一个月的数量,该应用程序计算出它的月份,并显示答案并显示该月的天数。当switch语句在Main方法中时,我让它工作,但是现在它显示错误的月份。我有以下代码:

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;
        }
    }

旧的开关声明是这样的:

        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;
    }

直到我改变为单独的方法,然后它从那里走下坡路。现在,即使我把它放回去,它仍然会混淆几个月?

如此困惑:S

提前感谢您的任何帮助......如果您能理解凌乱的代码:p

6 个答案:

答案 0 :(得分:5)

.NET Framework包含大量代码。有时候很难找到所需的东西,但是已经存在某些东西的可能性很高。而且,虽然搜索需要时间,但这是一个花费的时间,因为你为自己未来的工作提供了有用的知识

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);
         ......

    }
}

如果您还需要考虑闰年,您应该获得一年的输入,但这非常简单

答案 1 :(得分:1)

那是因为你的枚举让它全部混乱了。

31和30有重复值。

这是一个工作示例(但是有更多方法可以优化它。就像使用DateTime类一样)

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;
    }
}

答案 2 :(得分:1)

使用enum为常量创建符号名称。在这种情况下,这不是你想要的。

我认为你想要的是一个查找表,给定值A,返回一个值B.在你的情况下,你可以使用几个数组:

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 };

然后,您可以通过查找获得月份名称和天数:

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];
}

还有其他方法可以做到这一点,包括使用几个月和几天的结构或类,但这些是更高级的主题。

此外,.NET有一个DateTime structure具有所有这些功能,还有更多用于处理日期和时间的功能。在生产程序中,您可以使用它而不是自己动手。

答案 3 :(得分:0)

您可能需要考虑简化这一点并使您的枚举数与月份数匹配。然后将那个月的日期存储在其他地方。

然后你可以做(​​Months)userInput来获取枚举并消除至少一个switch语句。

只要枚举为每个值存储唯一的int,就可以使用Dictionary或其他方式存储每个月的日期。

答案 4 :(得分:0)

这不是你使用枚举的方式。

它们不仅仅是静态键值对:如果是,则可以使用的不仅仅是整数类型。不,它们不仅仅是整数类型的类型安全包装器。

你的问题是:

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
};

这意味着,就CLR而言,1月,3月,5月,7月,8月,10月和12月完全相同。与4月,6月,9月和11月相同。

这样做的正确方法是:

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

然后你的DetermineMonth方法就是这样:

public static Months DetermineMonth(int userInput)
{
    Months temp = (Months)userInput;
    return Enum.IsDefined(typeof(Months), temp) ? temp : Months.None; 
}

然后DetermineDaysInMonth就是这样:

public static int DetermineDaysInMonth(int userInput)
{
    if (!((Months[])Enum.GetValues(typeof(Months))).Contains((Months)userInput)
        return 0;
    else return DateTime.DaysInMonth(DateTime.Today.Year, userInput);
}

答案 5 :(得分:0)

您可以在enumExtension method返回天数 -

public enum Months
{
    January,
    February,
    March,
    April,
    May,
    June,
    July,
    August,
    September,
    October,
    November,
    December
}

public static class MonthsExtensions
{
    public static int DaysInMonths(this Months month)
    {
        switch (month)
        {
            case Months.January:
            case Months.March:
            case Months.May:
            case Months.July:
            case Months.August:
            case Months.October:
            case Months.December:
                return 31;

            case Months.April:
            case Months.June:
            case Months.September:
            case Months.November:
                return 30;

            case Months.February:
                return 28;
        }
        return 0;
    }

然后您可以获得这样的天数 -

int daysInMonths = Months.January.DaysInMonths();