在c#中将字符串转换为枚举值的最佳方法是什么?
我有一个包含枚举值的HTML选择标记。当页面被发布时,我想获取值(将以字符串的形式)并将其转换为相应的枚举值。
在理想的情况下,我可以这样做:
StatusEnum MyStatus = StatusEnum.Parse("Active");
但这不是有效的代码。
在c#中将字符串转换为枚举值的最佳方法是什么?
我有一个包含枚举值的HTML选择标记。当页面被发布时,我想获取值(将以字符串的形式)并将其转换为相应的枚举值。
在理想的情况下,我可以这样做:
StatusEnum MyStatus = StatusEnum.Parse("Active");
但这不是有效的代码。
当前回答
在。net Core和。net Framework≥4.0中,有一个通用的解析方法:
Enum.TryParse("Active", out StatusEnum myStatus);
这也包括c# 7的新内联变量,因此它执行try-parse,转换为显式枚举类型,并初始化+填充myStatus变量。
如果你能使用c# 7和最新的。net,这是最好的方法。
原来的答案
在。net中,它相当丑陋(直到4或以上):
StatusEnum MyStatus = (StatusEnum) Enum.Parse(typeof(StatusEnum), "Active", true);
我倾向于将其简化为:
public static T ParseEnum<T>(string value)
{
return (T) Enum.Parse(typeof(T), value, true);
}
然后我可以这样做:
StatusEnum MyStatus = EnumUtil.ParseEnum<StatusEnum>("Active");
评论中建议的一个选项是添加一个扩展,这很简单:
public static T ToEnum<T>(this string value)
{
return (T) Enum.Parse(typeof(T), value, true);
}
StatusEnum MyStatus = "Active".ToEnum<StatusEnum>();
最后,如果字符串不能被解析,你可能想要使用一个默认enum:
public static T ToEnum<T>(this string value, T defaultValue)
{
if (string.IsNullOrEmpty(value))
{
return defaultValue;
}
T result;
return Enum.TryParse<T>(value, true, out result) ? result : defaultValue;
}
这就要求:
StatusEnum MyStatus = "Active".ToEnum(StatusEnum.None);
然而,我会小心地添加这样的扩展方法到字符串(没有命名空间控制),它将出现在字符串的所有实例上,无论它们是否持有enum(因此1234.ToString(). toenum (statusenume . none)将是有效的,但毫无意义)。通常最好避免用只应用于非常特定的上下文的额外方法来混淆微软的核心类,除非您的整个开发团队都非常了解这些扩展的作用。
其他回答
首先,你需要装饰你的枚举,像这样:
public enum Store : short
{
[Description("Rio Big Store")]
Rio = 1
}
在。net 5中,我创建了这个扩展方法:
//The class also needs to be static, ok?
public static string GetDescription(this System.Enum enumValue)
{
FieldInfo fi = enumValue.GetType().GetField(enumValue.ToString());
DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(
typeof(DescriptionAttribute), false);
if (attributes != null && attributes.Length > 0) return attributes[0].Description;
else return enumValue.ToString();
}
现在你有一个扩展方法可以在任何枚举中使用
是这样的:
var Desc = Store.Rio.GetDescription(); //Store is your Enum
您正在寻找枚举。解析。
SomeEnum enum = (SomeEnum)Enum.Parse(typeof(SomeEnum), "EnumValue");
<Extension()>
Public Function ToEnum(Of TEnum)(ByVal value As String, ByVal defaultValue As TEnum) As TEnum
If String.IsNullOrEmpty(value) Then
Return defaultValue
End If
Return [Enum].Parse(GetType(TEnum), value, True)
End Function
这里的大多数答案都要求您在每次调用扩展方法时始终传递枚举的默认值。如果你不想采用这种方法,你可以像下面这样实现它:
public static TEnum ToEnum<TEnum>(this string value) where TEnum : struct
{
if (string.IsNullOrWhiteSpace(value))
return default(TEnum);
return Enum.TryParse(value, true, out TEnum result) ? result : default(TEnum);
}
使用默认文字(可从c# 7.1获得)
public static TEnum ToEnum<TEnum>(this string value, TEnum defaultValue = default) where TEnum : struct
{
if (string.IsNullOrWhiteSpace(value))
return defaultValue ;
return Enum.TryParse(value, true, out TEnum result) ? result : defaultValue ;
}
更好的是:
public static TEnum ToEnum<TEnum>(this string value) where TEnum : struct
{
if (string.IsNullOrWhiteSpace(value))
return default;
return Enum.TryParse(value, true, out TEnum result) ? result : default;
}
如果你想在null或空时使用默认值(例如,当从配置文件检索时,该值不存在),并在字符串或数字不匹配任何enum值时抛出异常。不过要注意提莫的回答(https://stackoverflow.com/a/34267134/2454604)。
public static T ParseEnum<T>(this string s, T defaultValue, bool ignoreCase = false)
where T : struct, IComparable, IConvertible, IFormattable//If C# >=7.3: struct, System.Enum
{
if ((s?.Length ?? 0) == 0)
{
return defaultValue;
}
var valid = Enum.TryParse<T>(s, ignoreCase, out T res);
if (!valid || !Enum.IsDefined(typeof(T), res))
{
throw new InvalidOperationException(
$"'{s}' is not a valid value of enum '{typeof(T).FullName}'!");
}
return res;
}