简体   繁体   中英

How do I properly switch with enums in C#?

I'm having trouble understanding how enums work in C#, since they print their own "name" rather than the value they represents. As an example I want to translate a weekday to another language using enums. These represents the day of the week.

enum Weekdays { Mon = 1, Tue, Wed, Thu, Fri, Sat, Sun };

My following method is the problem. If I don't have the (int)-casts on each of the cases, it will not compile due to type differences(?).

// Returns weekday in Norwegian.
private static string translateWeekday(int nummer)
{
    switch (nummer)
    {
        case (int)Weekdays.Mon:
            return "Mandag";
        /* ...... */
        case (int)Weekdays.Sun:
            return "Søndag";
    }
    return "Invalid input.";
}

I test my program with this. I also have to cast this one.

static void Main(string[] args)
{
    var ukedag = translateWeekday((int)Weekdays.Tue);
    Console.WriteLine(ukedag);
}

My actual question now is why do I need these casts and why doesn't C# print out the values, but the names of each enum if I try to print them out? And in my example, how should I do it properly (ie not have to use casts 7 times in a switch, which seems unnecessary)?

Simply change

private static string translateWeekday(int nummer)

to

private static string translateWeekday(Weekdays nummer)

and remove all the casts.

why doesn't C# print out the values, but the names of each enum if I try to print them out?

An enum is a type that has a special ToString that, by default, "prints" the name of the value instead of the value.

From Enum.ToString

and (if) there is a named constant equal to the value of this instance, then the return value is a string containing the name of the constant

You can use the .ToString("d") to print the "value" of an enum.

string str1 = Weekdays.Mon.ToString(); // Mon
string str2 = Weekdays.Mon.ToString("d"); // 1

You could use DateTimeFormatInfo.CurrentInfo.GetDayName( DateTime.Today.DayOfWeek ) to get the localized(in your case norwegian) day-name. So no need for your Weekdays -enum since there is already the DayOfWeek -enum .

You can even specify the culture you want to use explicitly:

var norwegianCulture = new CultureInfo("nn-NO");
string dayName = norwegianCulture.DateTimeFormat.GetDayName(DateTime.Today.DayOfWeek); // torsdag
dayName = norwegianCulture.DateTimeFormat.GetDayName(DayOfWeek.Monday); //måndag

If you can't/don't want to change the parameter type, you can do the cast earlier:

switch ((Weekdays)nummer)
{
    case Weekdays.Mon:
        return "Mandag";
    /* ...... */
    case Weekdays.Sun:
        return "Søndag";
}

I usually, in such cases, decorate the enumeration values with the 'DescriptionAttribute' found in the System.ComponentModel namespace, providing the required textual description and I have the following extension method that returns the text specified for the corresponding enumeration value:

public static string Description(this Enum value)
{
    FieldInfo field = value.GetType().GetField(value.ToString());
    DescriptionAttribute descriptionAttribute = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)) 
                                                as DescriptionAttribute;

    if (descriptionAttribute == null || string.IsNullOrEmpty(descriptionAttribute.Description))
    {
        return value.ToString();
    }

    return descriptionAttribute.Description;
}

So in your case you can define the enumeration as:

enum Weekdays
    {
        [Description("Mandag")]
        Mon = 1,
        [Description("Søndag")]
        Sun, 
    }

and then write

 Weekdays today = Weekdays.Mon;
 Console.WriteLine(today.Description());
 /// <summary>
  /// An enum class of days
  /// </summary>
  public enum Days
  {
    Sunday= 0,
    Monday= 1,
    Tuesday= 2,
    Wednesday=3,
    Thursday=4,
    Friday= 5,
    Saturday= 6
  }

The enum class

switch (type)
      {
        case 0:
          return Days.Sunday.ToString();
        case 1:
          return Days.Monday.ToString();
        case 2:
          return Days.Tuesday.ToString();
        case 3:
          return Days.Wednesday.ToString();
        case 4:
          return Days.Thursday.ToString();
        case 5:
          return Days.Friday.ToString();
        case 6:
          return Days.Saturday.ToString();
        default:
          return string.Empty;
       }

There is also a way to use descriptors above the enum values, so you can just call .Description and get the string representation of the value.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM