如何通过字符串或整数获取枚举值

197

如果我有枚举字符串或枚举整数值,我该如何获取枚举值。例如:如果我有以下枚举:

public enum TestEnum
{
    Value1 = 1,
    Value2 = 2,
    Value3 = 3
}

现在我有一个字符串变量,其值为"value1",如下所示:

string str = "Value1" 

或者在一些 int 变量中,我有值为 2 的变量,如下:

or in some int variable I have the value 2 like

int a = 2;

我该如何获取枚举类的实例?我需要一个通用方法,在其中提供枚举类和输入字符串或整数值以获取枚举类的实例。


可能是 通过字符串获取枚举int值的方法 的重复。 - user3559224
14个回答

383

不,你不想要一个通用的方法。这个简单多了:

MyEnum myEnum = (MyEnum)myInt;

MyEnum myEnum = (MyEnum)Enum.Parse(typeof(MyEnum), myString);

我认为它也会更快。


1
这实际上是做这件事的正确方式。之所以没有IParsable接口,原因与没有通用的解析类型的方式相同。 - Johannes
1
@Johannes 你是什么意思?有一种通用的方法,可以参考我的答案和其他人的答案。 - Sriram Sakthivel
1
@SriramSakthivel OP所描述的问题已经像KendallFrey展示的那样解决了。通用解析无法完成-请参见此处:http://www.informit.com/blogs/blog.aspx?uk=Why-no-IParseable-interface。与C#“内置”解决方案相比,任何其他解决方案都没有优势。您最多可以拥有一个ICanSetFromString<T>,其中您创建并初始化一个对象以其default(T)为默认值,并在下一步中传递一个代表性字符串。这接近于OP给出的答案-但是这是毫无意义的,因为通常这是一个设计问题,系统设计中错过了更大的要点。 - Johannes
5
我认为现在这个可以了,更加简练了:Enum.Parse(myString); - Phil B
2
这种方法的一个问题可能是(取决于用例):如果myInt具有无法映射到枚举值的值,则没有错误,并且myEnum仅接受相应的int值(枚举值最终是int值)。 - Grimm
显示剩余2条评论

39

有许多方法可以做到这一点,但如果您需要一个简单的示例,这个示例就可以了。只需要增加必要的防御性编码来检查类型安全和无效解析等问题。

    /// <summary>
    /// Extension method to return an enum value of type T for the given string.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="value"></param>
    /// <returns></returns>
    public static T ToEnum<T>(this string value)
    {
        return (T) Enum.Parse(typeof(T), value, true);
    }

    /// <summary>
    /// Extension method to return an enum value of type T for the given int.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="value"></param>
    /// <returns></returns>
    public static T ToEnum<T>(this int value)
    {
        var name = Enum.GetName(typeof(T), value);
        return name.ToEnum<T>();
    }

27

如果您使用TryParseParseToObject方法,那么这将变得更加简单。

public static class EnumHelper
{
    public static  T GetEnumValue<T>(string str) where T : struct, IConvertible
    {
        Type enumType = typeof(T);
        if (!enumType.IsEnum)
        {
            throw new Exception("T must be an Enumeration type.");
        }
        return Enum.TryParse(str, true, out T val) ? val : default;
    }

    public static T GetEnumValue<T>(int intValue) where T : struct, IConvertible
    {
        Type enumType = typeof(T);
        if (!enumType.IsEnum)
        {
            throw new Exception("T must be an Enumeration type.");
        }
        
        return (T)Enum.ToObject(enumType, intValue);
    }
}

如评论中由@chrfin指出的那样,您可以通过在参数类型前添加this而将其轻松地变成扩展方法,这可能会很方便。


2
现在还要将this添加到参数中,并使EnumHelper静态化,这样您也可以将它们用作扩展(请参见我的答案,但是您对其余部分有更好/完整的代码)... - Christoph Fink
@chrfin 不错的想法,但我不喜欢它,因为当我们有命名空间在作用域内时,它会在智能感知中弹出,这是不必要的。我猜这会很烦人。 - Sriram Sakthivel
1
@chrfin 感谢您的评论,我已将其作为注释添加到我的答案中。 - Sriram Sakthivel

13

7
以下是在C#中通过字符串获取枚举值的方法。
///
/// Method to get enumeration value from string value.
///
///
///

public T GetEnumValue<T>(string str) where T : struct, IConvertible
{
    if (!typeof(T).IsEnum)
    {
        throw new Exception("T must be an Enumeration type.");
    }
    T val = ((T[])Enum.GetValues(typeof(T)))[0];
    if (!string.IsNullOrEmpty(str))
    {
        foreach (T enumValue in (T[])Enum.GetValues(typeof(T)))
        {
            if (enumValue.ToString().ToUpper().Equals(str.ToUpper()))
            {
                val = enumValue;
                break;
            }
        }
    }

    return val;
}

以下是在C#中通过整数获取枚举值的方法。
///
/// Method to get enumeration value from int value.
///
///
///

public T GetEnumValue<T>(int intValue) where T : struct, IConvertible
{
    if (!typeof(T).IsEnum)
    {
        throw new Exception("T must be an Enumeration type.");
    }
    T val = ((T[])Enum.GetValues(typeof(T)))[0];

    foreach (T enumValue in (T[])Enum.GetValues(typeof(T)))
    {
        if (Convert.ToInt32(enumValue).Equals(intValue))
        {
            val = enumValue;
            break;
        }             
    }
    return val;
}

如果我有如下枚举:

public enum TestEnum
{
    Value1 = 1,
    Value2 = 2,
    Value3 = 3
}

那么我可以将上述方法用作如下:

然后我可以将上述方法用作如下:

TestEnum reqValue = GetEnumValue<TestEnum>("Value1");  // Output: Value1
TestEnum reqValue2 = GetEnumValue<TestEnum>(2);        // OutPut: Value2

希望这能有所帮助。


4
请问您能否提供此信息的来源参考? - JonH
为了编译这个,我不得不修改第一行为 public T GetEnumValue(int intValue) where T : struct, IConvertible同时注意末尾可能会有一个多余的 '}'。 - Avi

3

现在可以使用Enum.TryParse方法:

MyType myType;
bool isValidEnum = Enum.TryParse(yourStringValue, out myType);

如果"yourStringValue"不属于MyType枚举类型,则isValidEnum为false。
谢谢。

3
我认为您忘记了泛型类型定义:

我认为您忘记了泛型类型定义:

public T GetEnumValue<T>(int intValue) where T : struct, IConvertible // <T> added

而您可以将其改进为最方便的形式,例如:

public static T ToEnum<T>(this string enumValue) : where T : struct, IConvertible
{
    return (T)Enum.Parse(typeof(T), enumValue);
}

然后你可以这样做:
TestEnum reqValue = "Value1".ToEnum<TestEnum>();

3
尝试像这样做:
  public static TestEnum GetMyEnum(this string title)
        {    
            EnumBookType st;
            Enum.TryParse(title, out st);
            return st;          
         }

所以你可以这样做

TestEnum en = "Value1".GetMyEnum();

3

只需尝试这个

这是另一种方法

public enum CaseOriginCode
{
    Web = 0,
    Email = 1,
    Telefoon = 2
}

public void setCaseOriginCode(string CaseOriginCode)
{
    int caseOriginCode = (int)(CaseOriginCode)Enum.Parse(typeof(CaseOriginCode), CaseOriginCode);
}

2

从SQL数据库中获取枚举类型:

SqlDataReader dr = selectCmd.ExecuteReader();
while (dr.Read()) {
   EnumType et = (EnumType)Enum.Parse(typeof(EnumType), dr.GetString(0));
   ....         
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接