【问题标题】:How to get enum value by string or int如何通过字符串或整数获取枚举值
【发布时间】:2014-06-27 03:43:24
【问题描述】:

如果我有枚举字符串或枚举 int 值,我如何获取枚举值。例如:如果我有如下枚举:

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

在一些字符串变量中,我的值“value1”如下:

string str = "Value1" 

或者在一些 int 变量中我有值 2 像

int a = 2;

如何获取 enum 的实例?我想要一个通用方法,我可以提供枚举和输入字符串或 int 值来获取枚举实例。

【问题讨论】:

标签: c# enums


【解决方案1】:

不,您不想要通用方法。这更容易:

MyEnum myEnum = (MyEnum)myInt;

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

我认为它也会更快。

【讨论】:

  • 这实际上是正确的做法。与没有 IParsable 接口的原因相同,没有通用的方法来解析类型。
  • @Johannes 你这是什么意思?有一个通用的方法,参考我的答案和其他的。
  • @SriramSakthivel OP 描述的问题已经解决,就像 KendallFrey 展示的那样。无法进行通用解析 - 请参见此处:informit.com/blogs/blog.aspx?uk=Why-no-IParseable-interface。与 C# 的“板载”解决方案相比,任何其他解决方案都没有优势。您可以拥有的最大值是 ICanSetFromString ,您可以在其中创建对象并将其初始化为其默认值(T),然后在下一步中传入代表字符串。这与 OP 给出的答案很接近——但这毫无意义,因为通常这是一个设计问题,并且错过了系统设计中更大的一点。
  • 我认为现在可行,它更简洁一点:Enum.Parse(myString);
  • 这种方法的一个问题可能是(取决于用例):如果 myInt 有一个无法映射到枚举值的值,则没有错误,并且 myEnum 只需获取相应的 int 值(枚举值最终是 int 值)。
【解决方案2】:

有很多方法可以做到这一点,但如果你想要一个简单的例子,这将是可行的。它只需要通过必要的防御性编码来增强,以检查类型安全和无效解析等。

    /// <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>();
    }

【讨论】:

    【解决方案3】:

    如果您使用TryParse 或Parse 和ToObject 方法会更简单。

    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 在 cmets 中所指出的,您只需在参数类型前添加this 就可以非常方便地使其成为扩展方法。

    【讨论】:

    • 现在还要在参数中添加一个this 并使EnumHelper 静态,您也可以将它们用作扩展名(请参阅我的答案,但其余部分您有更好/完整的代码)。 ..
    • @chrfin 好主意,但我不喜欢它,因为它会出现在智能感知中,当我们在范围内有命名空间时不需要它。我猜这会很烦人。
    • @chrfin 感谢您的评论,在我的回答中作为注释添加。
    【解决方案4】:

    以下是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#中通过int获取枚举值的方法。

    ///
    /// 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
    

    希望这会有所帮助。

    【讨论】:

    • 您能否提供参考资料,说明您是从哪里获得的?
    • 为了进行编译,我必须将第一行修改为 public T GetEnumValue(int intValue) where T : struct, IConvertible 还要注意末尾的额外“}”
    【解决方案5】:

    我想你忘记了泛型类型定义:

    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>();
    

    【讨论】:

      【解决方案6】:

      试试这样的

        public static TestEnum GetMyEnum(this string title)
              {    
                  EnumBookType st;
                  Enum.TryParse(title, out st);
                  return st;          
               }
      

      所以你可以这样做

      TestEnum en = "Value1".GetMyEnum();
      

      【讨论】:

        【解决方案7】:

        试试这个

        这是另一种方式

        public enum CaseOriginCode
        {
            Web = 0,
            Email = 1,
            Telefoon = 2
        }
        
        public void setCaseOriginCode(string CaseOriginCode)
        {
            int caseOriginCode = (int)(CaseOriginCode)Enum.Parse(typeof(CaseOriginCode), CaseOriginCode);
        }
        

        【讨论】:

          【解决方案8】:

          正如@Phil B 在@Kendall Frey 的answer 的cmets 中所建议的,这可以非常简洁地用于字符串。

          Enum.Parse<MyEnum>(myString);
          

          自从@Kendall Frey 的answer 添加这个给我一个运行时错误,而@Phil B 的修订没有。

          【讨论】:

            【解决方案9】:

            从 SQL 数据库获取枚举,如:

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

            【讨论】:

              【解决方案10】:

              这里是一个获取字符串/值的例子

                  public enum Suit
                  {
                      Spades = 0x10,
                      Hearts = 0x11,
                      Clubs = 0x12,
                      Diamonds = 0x13
                  }
              
                  private void print_suit()
                  {
                      foreach (var _suit in Enum.GetValues(typeof(Suit)))
                      {
                          int suitValue = (byte)(Suit)Enum.Parse(typeof(Suit), _suit.ToString());
                          MessageBox.Show(_suit.ToString() + " value is 0x" + suitValue.ToString("X2"));
                      }
                  }
              

                  Result of Message Boxes
                  Spade value is 0x10
                  Hearts value is 0x11
                  Clubs value is 0x12
                  Diamonds value is 0x13
              

              【讨论】:

                【解决方案11】:

                您可以使用以下方法来做到这一点:

                public static Output GetEnumItem<Output, Input>(Input input)
                    {
                        //Output type checking...
                        if (typeof(Output).BaseType != typeof(Enum))
                            throw new Exception("Exception message...");
                
                        //Input type checking: string type
                        if (typeof(Input) == typeof(string))
                            return (Output)Enum.Parse(typeof(Output), (dynamic)input);
                
                        //Input type checking: Integer type
                        if (typeof(Input) == typeof(Int16) ||
                            typeof(Input) == typeof(Int32) ||
                            typeof(Input) == typeof(Int64))
                
                            return (Output)(dynamic)input;
                
                        throw new Exception("Exception message...");
                    }
                

                注意:此方法只是一个示例,您可以改进它。

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2022-07-15
                  • 1970-01-01
                  • 1970-01-01
                  • 2016-12-01
                  相关资源
                  最近更新 更多