在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");

我们不能假设输入是完全有效的,于是就用了@Keith的答案的变体:

public static TEnum ParseEnum<TEnum>(string value) where TEnum : struct
{
    TEnum tmp; 
    if (!Enum.TryParse<TEnum>(value, true, out tmp))
    {
        tmp = new TEnum();
    }
    return tmp;
}

我使用了class(具有解析和性能改进的Enum强类型版本)。我在GitHub上找到了它,它应该也适用于。net 3.5。它有一些内存开销,因为它缓冲了一个字典。

StatusEnum MyStatus = Enum<StatusEnum>.Parse("Active");

这篇博文是Enums - NET 3.5中更好的语法,更好的性能和TryParse。

和代码: https://github.com/damieng/DamienGKit/blob/master/CSharp/DamienG.Library/System/EnumT.cs

使用枚举。TryParse<T>(String, T)(≥.NET 4.0):

StatusEnum myStatus;
Enum.TryParse("Active", out myStatus);

使用c# 7.0的参数类型内联可以进一步简化:

Enum.TryParse("Active", out StatusEnum myStatus);