如何在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;
...
我以为枚举是常量。 我该如何解决?
(我无法将值解析为枚举,因为某些值超出了范围)
从C#6开始,您可以使用:case nameof(SomeEnum.SomeValue):
Nameof是在编译时求值的,简单地是一个与给定变量,类型或成员的(非限定)名称匹配的字符串。 当然,如果您重命名枚举选项名称,它也会随之更改。
将开关中的字符串转换为枚举值。
(ORDER)Enum.Parse(typeof(ORDER), value, true);
作为使用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版本:)
枚举是一个常量,但是.ToString()的结果不是。 就编译器而言,它是一个动态值。 您可能需要将切换用例转换为一系列if / else语句
您出于某种原因将其设计为枚举,但实际上并没有真正将其用作枚举。 为什么要采用枚举值并将其转换为字符串然后在开关中使用,而不是简单地使用枚举?
您说您无法将其解析为枚举,因为某些值超出了枚举范围。 然后要问的问题是:“为什么?” 如果允许未定义的值,那么拥有枚举有什么意义? 当您获得未定义的值时,您想发生什么? 如果对于任何未定义的值都是相同的,则可以使用默认大小写。 如果不是,则可以包括与数字表示形式匹配的其他情况。
如果确实返回了字符串,那么您可能不想使用枚举。 相反,您想创建一个包含公共字符串常量的公共静态类,然后可以在开关中使用它。 这里的技巧是,评估将以区分大小写的方式进行。
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;
}
(您可能还需要清理外壳。)
如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;
}
枚举值是常量,但是您尝试使用方法(ORDER.partial01.ToString())的结果,而不是常量。
我认为最好的选择是将其切换为使用if / else if / else语句,而不是进行切换。 这将允许您使用所需的逻辑。
另外,如果将字符串切换为枚举值,则可以直接打开枚举值。 但是,您无法通过一个开关打开enum + null +其他字符串。
你不能只是说
case "partial01":
?
枚举是常量,但是ToString()是返回值的函数。 根据枚举对象的实例被调用。
这是两个语句:
ORDER.partial01.ToString()
ORDER.partial02.ToString()
调用相同的函数,但返回两个不同的值,因此对函数.ToString()的调用本身不是常数。
就编译器而言,这不是静态值,因为它是一个函数调用:
ORDER.partial01.ToString()
因此,您不能将其用作case语句中的比较。 但是,您可以简单地执行以下操作:
case "partial01"
这将起作用,因为枚举值和字符串相同。
只需定义一个全局变量
static ORDER orderstr;
现在您可以在页面中的任何地方设置值orderstr
public enum ORDER
{
unknown,
partial01,
partial12,
partial23,
}
switch (orderstr)
{
case Order.Partial01:
break;
default:
break;
}
使用扩展
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();