如何在case语句中使用C#枚举值的字符串值?

我已将C#枚举定义为

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

并可以将其值用作字符串,如下所示:

            string ss = ORDER.partial01.ToString();

但是,当我尝试在case语句中使用它时,它无法编译:

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

        break;
  ...

我以为枚举是常量。 我该如何解决?

(我无法将值解析为枚举,因为某些值超出了范围)

peter.murray.rust asked 2020-02-22T16:55:34Z
12个解决方案
90 votes

从C#6开始,您可以使用:case nameof(SomeEnum.SomeValue):

Nameof是在编译时求值的,简单地是一个与给定变量,类型或成员的(非限定)名称匹配的字符串。 当然,如果您重命名枚举选项名称,它也会随之更改。

Timo answered 2020-02-22T16:56:07Z
44 votes

将开关中的字符串转换为枚举值。

(ORDER)Enum.Parse(typeof(ORDER), value, true);
sipwiz answered 2020-02-22T16:56:27Z
30 votes

作为使用T Enum.Parse<T>(string value)的替代方法,您可以先将字符串转换为enum。 但是,如果选项的数量很少,可能就没有多大意义:

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
}

*长叹*,如果只有内置的T Enum.Parse<T>(string value)和TryParse版本:)

Thorarin answered 2020-02-22T16:56:52Z
26 votes

枚举是一个常量,但是.ToString()的结果不是。 就编译器而言,它是一个动态值。 您可能需要将切换用例转换为一系列if / else语句

Joel Martinez answered 2020-02-22T16:55:42Z
12 votes

您出于某种原因将其设计为枚举,但实际上并没有真正将其用作枚举。 为什么要采用枚举值并将其转换为字符串然后在开关中使用,而不是简单地使用枚举?

您说您无法将其解析为枚举,因为某些值超出了枚举范围。 然后要问的问题是:“为什么?” 如果允许未定义的值,那么拥有枚举有什么意义? 当您获得未定义的值时,您想发生什么? 如果对于任何未定义的值都是相同的,则可以使用默认大小写。 如果不是,则可以包括与数字表示形式匹配的其他情况。

如果确实返回了字符串,那么您可能不想使用枚举。 相反,您想创建一个包含公共字符串常量的公共静态类,然后可以在开关中使用它。 这里的技巧是,评估将以区分大小写的方式进行。

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

(您可能还需要清理外壳。)

Scott Dorman answered 2020-02-22T16:57:29Z
5 votes

如Thorarin所述,如果您的switch语句只能包含enum个案例,请先将您的string转换为enum。 至少从.Net framework 4开始,您可以使用此处定义的2759062921417317327620方法,并执行以下操作:

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;
}
Dave Clemmer answered 2020-02-22T16:57:50Z
2 votes

枚举值是常量,但是您尝试使用方法(ORDER.partial01.ToString())的结果,而不是常量。

我认为最好的选择是将其切换为使用if / else if / else语句,而不是进行切换。 这将允许您使用所需的逻辑。

另外,如果将字符串切换为枚举值,则可以直接打开枚举值。 但是,您无法通过一个开关打开enum + null +其他字符串。

Reed Copsey answered 2020-02-22T16:58:20Z
1 votes

你不能只是说

case "partial01":

?

eWolf answered 2020-02-22T16:58:44Z
1 votes

枚举是常量,但是ToString()是返回值的函数。 根据枚举对象的实例被调用。

这是两个语句:

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

调用相同的函数,但返回两个不同的值,因此对函数.ToString()的调用本身不是常数。

Rune FS answered 2020-02-22T16:59:14Z
1 votes

就编译器而言,这不是静态值,因为它是一个函数调用:

ORDER.partial01.ToString()

因此,您不能将其用作case语句中的比较。 但是,您可以简单地执行以下操作:

case "partial01"

这将起作用,因为枚举值和字符串相同。

John Fisher answered 2020-02-22T16:59:43Z
0 votes

只需定义一个全局变量

static ORDER orderstr;

现在您可以在页面中的任何地方设置值orderstr

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

switch (orderstr)
{
    case Order.Partial01:
        break;
    default:
        break;
}
Utkarsh Kumar answered 2020-02-22T17:00:07Z
0 votes

使用扩展

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

Gender.Male.ToGender();
Fatih Erol answered 2020-02-22T17:00:31Z
translate from https://stackoverflow.com:/questions/1273228/how-can-i-use-the-string-value-of-a-c-sharp-enum-value-in-a-case-statement