在c#中将字符串转换为枚举值的最佳方法是什么?

我有一个包含枚举值的HTML选择标记。当页面被发布时,我想获取值(将以字符串的形式)并将其转换为相应的枚举值。

在理想的情况下,我可以这样做:

StatusEnum MyStatus = StatusEnum.Parse("Active");

但这不是有效的代码。


当前回答

我发现这里没有考虑具有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
}

其他回答

您可以使用默认值扩展接受的答案以避免异常:

public static T ParseEnum<T>(string value, T defaultValue) where T : struct
{
    try
    {
        T enumValue;
        if (!Enum.TryParse(value, true, out enumValue))
        {
            return defaultValue;
        }
        return enumValue;
    }
    catch (Exception)
    {
        return defaultValue;
    }
}

然后你这样称呼它:

StatusEnum MyStatus = EnumUtil.ParseEnum("Active", StatusEnum.None);

如果默认值不是enum,则为enum。TryParse将失败并抛出一个被捕获的异常。

在我们的代码中许多地方使用了这个函数多年之后,也许添加这个操作降低性能的信息是很好的!

您正在寻找枚举。解析。

SomeEnum enum = (SomeEnum)Enum.Parse(typeof(SomeEnum), "EnumValue");

不确定什么时候添加的,但在Enum类上现在有一个

Parse<TEnum>(stringValue)

与问题中的例子一起用:

var MyStatus = Enum.Parse<StatusEnum >(“Active”)

或者忽略大小写:

var MyStatus = Enum.Parse<StatusEnum >(“active”, true)

下面是它使用的反编译方法:

    [NullableContext(0)]
    public static TEnum Parse<TEnum>([Nullable(1)] string value) where TEnum : struct
    {
      return Enum.Parse<TEnum>(value, false);
    }

    [NullableContext(0)]
    public static TEnum Parse<TEnum>([Nullable(1)] string value, bool ignoreCase) where TEnum : struct
    {
      TEnum result;
      Enum.TryParse<TEnum>(value, ignoreCase, true, out result);
      return result;
    }

使用TryParse的超级简单代码:

var value = "Active";

StatusEnum status;
if (!Enum.TryParse<StatusEnum>(value, out status))
    status = StatusEnum.Unknown;

我发现这里没有考虑具有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
}