PWL
PWL

Reputation: 466

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 (i.e. not have to use casts 7 times in a switch, which seems unnecessary)?

Upvotes: 2

Views: 694

Answers (5)

V. Oikonomakos
V. Oikonomakos

Reputation: 119

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

Upvotes: 1

Eric Bowser
Eric Bowser

Reputation: 62

 /// <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.

Upvotes: 0

Tim Schmelter
Tim Schmelter

Reputation: 460138

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

Upvotes: 4

D Stanley
D Stanley

Reputation: 152556

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

Upvotes: 3

xanatos
xanatos

Reputation: 111860

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

Upvotes: 8

Related Questions