在c#中将字符串转换为枚举值的最佳方法是什么?
我有一个包含枚举值的HTML选择标记。当页面被发布时,我想获取值(将以字符串的形式)并将其转换为相应的枚举值。
在理想的情况下,我可以这样做:
StatusEnum MyStatus = StatusEnum.Parse("Active");
但这不是有效的代码。
在c#中将字符串转换为枚举值的最佳方法是什么?
我有一个包含枚举值的HTML选择标记。当页面被发布时,我想获取值(将以字符串的形式)并将其转换为相应的枚举值。
在理想的情况下,我可以这样做:
StatusEnum MyStatus = StatusEnum.Parse("Active");
但这不是有效的代码。
当前回答
这里的大多数答案都要求您在每次调用扩展方法时始终传递枚举的默认值。如果你不想采用这种方法,你可以像下面这样实现它:
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;
}
其他回答
object Enum.Parse(System.Type enumType, string value, bool ignoreCase);
如果你有一个名为mood的enum,它会像这样:
enum Mood
{
Angry,
Happy,
Sad
}
// ...
Mood m = (Mood) Enum.Parse(typeof(Mood), "Happy", true);
Console.WriteLine("My mood is: {0}", m.ToString());
枚举。解析是你的朋友:
StatusEnum MyStatus = (StatusEnum)Enum.Parse(typeof(StatusEnum), "Active");
请注意:
enum Example
{
One = 1,
Two = 2,
Three = 3
}
Enum.(Try)Parse()接受多个逗号分隔的参数,并将它们与二进制'或' | '组合。你不能禁用这个,在我看来,你几乎从来都不想要它。
var x = Enum.Parse("One,Two"); // x is now Three
即使没有定义3,x仍然会得到int值3。更糟糕的是:枚举. parse()可以给你一个甚至没有为枚举定义的值!
我不想经历用户自愿或不情愿触发这种行为的后果。
此外,正如其他人所提到的,对于大型枚举(即可能值的数量呈线性),性能不太理想。
我的建议如下:
public static bool TryParse<T>(string value, out T result)
where T : struct
{
var cacheKey = "Enum_" + typeof(T).FullName;
// [Use MemoryCache to retrieve or create&store a dictionary for this enum, permanently or temporarily.
// [Implementation off-topic.]
var enumDictionary = CacheHelper.GetCacheItem(cacheKey, CreateEnumDictionary<T>, EnumCacheExpiration);
return enumDictionary.TryGetValue(value.Trim(), out result);
}
private static Dictionary<string, T> CreateEnumDictionary<T>()
{
return Enum.GetValues(typeof(T))
.Cast<T>()
.ToDictionary(value => value.ToString(), value => value, StringComparer.OrdinalIgnoreCase);
}
public TEnum ToEnum<TEnum>(this string value, TEnum defaultValue){
if (string.IsNullOrEmpty(value))
return defaultValue;
return Enum.Parse(typeof(TEnum), value, true);}
我发现这里没有考虑具有EnumMember值的enum值的情况。我们开始吧:
using System.Runtime.Serialization;
public static TEnum ToEnum<TEnum>(this string value, TEnum defaultValue) where TEnum : struct
{
if (string.IsNullOrEmpty(value))
{
return defaultValue;
}
TEnum result;
var enumType = typeof(TEnum);
foreach (var enumName in Enum.GetNames(enumType))
{
var fieldInfo = enumType.GetField(enumName);
var enumMemberAttribute = ((EnumMemberAttribute[]) fieldInfo.GetCustomAttributes(typeof(EnumMemberAttribute), true)).FirstOrDefault();
if (enumMemberAttribute?.Value == value)
{
return Enum.TryParse(enumName, true, out result) ? result : defaultValue;
}
}
return Enum.TryParse(value, true, out result) ? result : defaultValue;
}
枚举的例子是:
public enum OracleInstanceStatus
{
Unknown = -1,
Started = 1,
Mounted = 2,
Open = 3,
[EnumMember(Value = "OPEN MIGRATE")]
OpenMigrate = 4
}