How can I use the string value of a C# enum value in a case statement?

C#StringEnums

C# Problem Overview


I have defined a C# enum as

public enum ORDER
{
    ...
    unknown,
    partial01,
    partial12,
    partial23,
}

and can use its value as a string as in:

            string ss = ORDER.partial01.ToString();

However when I try to use it in a case statement it fails to compile:

string value = ...
switch (value)
{
    case null:
        break;
    case "s":
        // OK
        break;
    case ORDER.partial01.ToString():
        // compiler throws "a constant value is expected"

        break;
  ...

I thought enums were constants. How do I get around this?

(I cannot parse the value into an enum as some of the values are outside the range)

C# Solutions


Solution 1 - C#

Since C# 6, you can use: case nameof(SomeEnum.SomeValue):

Nameof is evaluated at compile time, simply to a string that matches the (unqualified) name of the given variable, type, or member. Naturally, it changes right along should you ever rename the enum option name.

Solution 2 - C#

Convert the string in your switch to an enum value.

(ORDER)Enum.Parse(typeof(ORDER), value, true);

Solution 3 - C#

The enum is a constant, but the result of .ToString() is not. As far as the compiler is concerned, it is a dynamic value. You probably need to convert your switch case into a series of if/else statements

Solution 4 - C#

As an alternative to using if .. else, you could convert your string to an enum first. It would probably not make much sense if the number of options is small though:

if (Enum.IsDefined(typeof(ORDER), value))
{
    switch ((ORDER)Enum.Parse(typeof(ORDER), value)
    {
        case ORDER.partial01:
            // ... 
            break;
        case ORDER.partial12:
            // etc
    }
}
else
{
    // Handle values not in enum here if needed
}

*sigh* if only there was a built-in T Enum.Parse<T>(string value), and a TryParse version :)

Solution 5 - C#

You designed this as an enum for a reason, but you're not really making use of it as an enum. Why are you taking the enum value and converting it to a string to then use in the switch instead of simply using the enum?

You said that you can't parse this in to an enum because some of the values are outside the enum range. The question to ask then is, "Why?" What is the point of having the enum if you are allowing values that aren't defined? What is it that you want to happen when you get a value that isn't defined? If it's the same thing for any undefined value, then you can use the default case. If it's not, then you can include additional cases that match the numeric representation.

If you really do get strings back, then you probably don't want to use an enum. Instead you want to create a public static class containing public string constants, which you can then use in your switch. The trick here is that the evaluation will be done in a case sensitive manner.

public static class Order
{
   public const string Unknown = "Unknown";
   public const string Partial01 = "Partial01";
   public const string Partial12 = "Partial12";
   public const string Partial23 = "Partial23";
}

string value = Order.Partial01
switch (value)
{
   case Order.Partial01:
      break;

    default:
       // Code you might want to run in case you are
       // given a value that doesn't match.
       break;
}

(You might also want to clean up your casing.)

Solution 6 - C#

As Thorarin indicated, if your switch statement can contain only enum cases, convert your string to an enum first. At least as of .Net framework 4, you can use the Enum.TryParse()<TEnum> method as defined here and do something like:

ORDER orderEnum = ORDER.unknown;
Enum.TryParse<ORDER>(value, out orderEnum);

switch (orderEnum)
{
    case ORDER.unknown:
        // perhaps do something to deal with cases not matching
        // to known enum values, based on the string value
        break;
    case ORDER.partial01:
    case ORDER.partial12:
    case ORDER.partial23:
        // map value to known cases, etc.
        break;
}

Solution 7 - C#

Enum values are constants, but you're trying to use the results of a method (ORDER.partial01.ToString()), not a constant.

The best option, in my opinion, would be to just switch this around to using if/else if/else statements, instead of a switch. This would allow you to use the logic you are desiring.

Alternatively, if you switch your string into the enum value, you can switch on the enum values directly. You cannot switch on the enum + null + other strings, though, in one switch.

Solution 8 - C#

Couldn't you just instead say

case "partial01":

?

Solution 9 - C#

enums are constant but ToString() is a function returning a value. based on the instance of the enum object it's being called on.

That is the two statements:

ORDER.partial01.ToString()
ORDER.partial02.ToString()

calls the same function but returns two different values, so the call to the function .ToString() is in it self not a constant value.

Solution 10 - C#

This is not a static value as far as the compiler is concerned, since it is a function call:

ORDER.partial01.ToString()

Therefore, you can't use it as a comparison in a case statement. However, you can simply do this:

case "partial01"

That would work, since the enum value and the string are identical.

Solution 11 - C#

Use Extension

      public static string ToGender(this Gender enumValue)
        {
            switch (enumValue)
            {
                case Gender.Female:
                    return "Female";
                case Gender.Male:
                    return "Male";
                default:
                    return null;
            }
        }

Example

Gender.Male.ToGender();

Solution 12 - C#

simply you can define a global variable

static ORDER orderstr;

now you can set the value of orderstr anywhere in the page

public enum ORDER
{ 
    unknown,
    partial01,
    partial12,
    partial23,
}
        
switch (orderstr)
{
    case Order.Partial01:
        break;
    default:
        break;
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionpeter.murray.rustView Question on Stackoverflow
Solution 1 - C#TimoView Answer on Stackoverflow
Solution 2 - C#sipsorceryView Answer on Stackoverflow
Solution 3 - C#Joel MartinezView Answer on Stackoverflow
Solution 4 - C#ThorarinView Answer on Stackoverflow
Solution 5 - C#Scott DormanView Answer on Stackoverflow
Solution 6 - C#Dave ClemmerView Answer on Stackoverflow
Solution 7 - C#Reed CopseyView Answer on Stackoverflow
Solution 8 - C#eWolfView Answer on Stackoverflow
Solution 9 - C#Rune FSView Answer on Stackoverflow
Solution 10 - C#John FisherView Answer on Stackoverflow
Solution 11 - C#Fatih ErolView Answer on Stackoverflow
Solution 12 - C#Utkarsh KumarView Answer on Stackoverflow