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

时间:2009-08-13 16:52:28

标签: c# string enums

我已将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;
  ...

我认为枚举是常数。我该如何解决这个问题?

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

11 个答案:

答案 0 :(得分:74)

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

Nameof在编译时被评估,只是一个与给定变量,类型或成员的(非限定)名称匹配的字符串。当然,如果您重命名枚举选项名称,它会一直改变。

答案 1 :(得分:42)

将交换机中的字符串转换为枚举值。

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

答案 2 :(得分:30)

作为使用if .. else的替代方法,您可以先将字符串转换为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版本:)

答案 3 :(得分:25)

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

答案 4 :(得分:12)

你将此设计为枚举是有原因的,但你并没有真正将它作为枚举使用。为什么要获取枚举值并将其转换为字符串然后在开关中使用而不是简单地使用枚举?

你说你无法将其解析为枚举,因为某些值超出了枚举范围。那时要问的问题是,“为什么?”如果您允许未定义的值,那么拥有枚举的重点是什么?当你得到一个未定义的值时,你想要发生什么?如果对于任何未定义的值都是相同的,那么您可以使用默认情况。如果不是,那么您可以包含与数字表示匹配的其他案例。

如果你确实得到了字符串,那么你可能不想使用枚举。相反,您需要创建一个包含公共字符串常量的公共静态类,然后您可以在交换机中使用它们。这里的诀窍是评估将以区分大小写的方式完成。

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

(您可能还想清理外壳。)

答案 5 :(得分:4)

正如Thorarin指出的那样,如果您的switch语句只能包含enum个案例,请先将string转换为enum。至少从.Net framework 4开始,您可以使用定义hereEnum.TryParse()<TEnum>方法并执行以下操作:

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

答案 6 :(得分:2)

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

在我看来,最好的选择就是将其切换为使用if / else if / else语句而不是开关。这将允许您使用您想要的逻辑。

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

答案 7 :(得分:2)

你不能只是说

case "partial01":

答案 8 :(得分:1)

枚举是常量,但ToString()是一个返回值的函数。基于它被调用的枚举对象的实例。

这是两个陈述:

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

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

答案 9 :(得分:1)

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

ORDER.partial01.ToString()

因此,您不能在case语句中将其用作比较。但是,您可以这样做:

case "partial01"

这样可行,因为枚举值和字符串相同。

答案 10 :(得分:0)

只需定义全局变量

即可
static ORDER orderstr;

现在您可以在页面的任何位置设置orderstr的值

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

switch (orderstr)
{
    case Order.Partial01:
        break;
    default:
        break;
}