首页 文章

在C#中将int转换为枚举

提问于
浏览
2699

如何在C#中将 int 强制转换为 enum

22 回答

  • 6

    有时你有一个 MyEnum 类型的对象 . 喜欢

    var MyEnumType = typeof(MyEnumType);
    

    然后:

    Enum.ToObject(typeof(MyEnum), 3)
    
  • 39

    如果您已准备好使用4.0 .NET Framework,那么有一个新的Enum.TryParse()函数非常有用,可以很好地与[Flags]属性配合使用 . 见Enum.TryParse Method (String, TEnum%)

  • 15

    这将整数或字符串解析为目标枚举,在dot.NET 4.0中使用泛型,如上面的Tawani实用程序类中的部分匹配 . 我用它来转换可能不完整的命令行开关变量 . 由于枚举不能为null,因此您应该在逻辑上提供默认值 . 它可以像这样调用:

    var result = EnumParser<MyEnum>.Parse(valueToParse, MyEnum.FirstValue);
    

    这是代码:

    using System;
    
    public class EnumParser<T> where T : struct
    {
        public static T Parse(int toParse, T defaultVal)
        {
            return Parse(toParse + "", defaultVal);
        }
        public static T Parse(string toParse, T defaultVal) 
        {
            T enumVal = defaultVal;
            if (defaultVal is Enum && !String.IsNullOrEmpty(toParse))
            {
                int index;
                if (int.TryParse(toParse, out index))
                {
                    Enum.TryParse(index + "", out enumVal);
                }
                else
                {
                    if (!Enum.TryParse<T>(toParse + "", true, out enumVal))
                    {
                        MatchPartialName(toParse, ref enumVal);
                    }
                }
            }
            return enumVal;
        }
    
        public static void MatchPartialName(string toParse, ref T enumVal)
        {
            foreach (string member in enumVal.GetType().GetEnumNames())
            {
                if (member.ToLower().Contains(toParse.ToLower()))
                {
                    if (Enum.TryParse<T>(member + "", out enumVal))
                    {
                        break;
                    }
                }
            }
        }
    }
    

    FYI: 问题是关于整数,没人提到也会在Enum.TryParse()中显式转换

  • 125

    对于数值,这更安全,因为它将返回一个对象,无论如何:

    public static class EnumEx
    {
        static public bool TryConvert<T>(int value, out T result)
        {
            result = default(T);
            bool success = Enum.IsDefined(typeof(T), value);
            if (success)
            {
                result = (T)Enum.ToObject(typeof(T), value);
            }
            return success;
        }
    }
    
  • 3

    以下是稍微好一点的扩展方法

    public static string ToEnumString<TEnum>(this int enumValue)
            {
                var enumString = enumValue.ToString();
                if (Enum.IsDefined(typeof(TEnum), enumValue))
                {
                    enumString = ((TEnum) Enum.ToObject(typeof (TEnum), enumValue)).ToString();
                }
                return enumString;
            }
    
  • 19

    这是一个标识枚举的安全转换方法:

    public static bool TryConvertToEnum<T>(this int instance, out T result)
      where T: Enum
    {
      var enumType = typeof (T);
      var success = Enum.IsDefined(enumType, instance);
      if (success)
      {
        result = (T)Enum.ToObject(enumType, instance);
      }
      else
      {
        result = default(T);
      }
      return success;
    }
    
  • 11

    enter image description here

    要将字符串转换为ENUM或int转换为ENUM常量,我们需要使用Enum.Parse函数 . 这是一个youtube视频https://www.youtube.com/watch?v=4nhx4VwdRDk,它实际上演示了字符串,同样适用于int .

    代码如下所示,其中“red”是字符串,“MyColors”是具有颜色常数的颜色ENUM .

    MyColors EnumColors = (MyColors)Enum.Parse(typeof(MyColors), "Red");
    
  • 3252

    只是施展它:

    MyEnum e = (MyEnum)3;
    

    您可以使用Enum.IsDefined检查它是否在范围内:

    if (Enum.IsDefined(typeof(MyEnum), 3)) { ... }
    
  • 8

    在c#中将int转换为枚举的简单明了的方法:

    public class Program
        {
            public enum Color : int
            {
                Blue = 0,
                Black = 1,
                Green = 2,
                Gray = 3,
                Yellow =4
            }
    
            public static void Main(string[] args)
            {
                //from string
                Console.WriteLine((Color) Enum.Parse(typeof(Color), "Green"));
    
                //from int
                Console.WriteLine((Color)2);
    
                //From number you can also
                Console.WriteLine((Color)Enum.ToObject(typeof(Color) ,2));
            }
        }
    
  • 6

    从字符串:

    YourEnum foo = (YourEnum) Enum.Parse(typeof(YourEnum), yourString);
    // the foo.ToString().Contains(",") check is necessary for enumerations marked with an [Flags] attribute
    if (!Enum.IsDefined(typeof(YourEnum), foo) && !foo.ToString().Contains(","))
      throw new InvalidOperationException($"{yourString} is not an underlying value of the YourEnum enumeration.")
    

    来自int:

    YourEnum foo = (YourEnum)yourInt;
    

    Update:

    从数字你也可以

    YourEnum foo = (YourEnum)Enum.ToObject(typeof(YourEnum) , yourInt);
    
  • 6

    我正在使用这段代码将int转换为我的枚举:

    if (typeof(YourEnum).IsEnumDefined(valueToCast)) return (YourEnum)valueToCast;
    else { //handle it here, if its not defined }
    

    我觉得这是最好的解决方案 .

  • 96

    采用以下示例:

    int one = 1;
    MyEnum e = (MyEnum)one;
    
  • 9

    不同的投射方式 to and from Enum

    enum orientation : byte
    {
     north = 1,
     south = 2,
     east = 3,
     west = 4
    }
    
    class Program
    {
      static void Main(string[] args)
      {
        orientation myDirection = orientation.north;
        Console.WriteLine(“myDirection = {0}”, myDirection); //output myDirection =north
        Console.WriteLine((byte)myDirection); //output 1
    
        string strDir = Convert.ToString(myDirection);
            Console.WriteLine(strDir); //output north
    
        string myString = “north”; //to convert string to Enum
        myDirection = (orientation)Enum.Parse(typeof(orientation),myString);
    
    
     }
    }
    
  • 26

    稍微离开原来的问题,但我发现an answer to Stack Overflow question Get int value from enum很有用 . 使用 public const int 属性创建一个静态类,允许您轻松地收集一堆相关的 int 常量,然后在使用它们时不必将它们转换为 int .

    public static class Question
    {
        public static readonly int Role = 2;
        public static readonly int ProjectFunding = 3;
        public static readonly int TotalEmployee = 4;
        public static readonly int NumberOfServers = 5;
        public static readonly int TopBusinessConcern = 6;
    }
    

    显然,一些枚举类型的功能将会丢失,但是为了存储一堆数据库id常量,它似乎是一个非常整洁的解决方案 .

  • 754

    在我的情况下,我需要从WCF服务返回枚举 . 我还需要一个友好的名称,而不仅仅是enum.ToString() .

    这是我的WCF课程 .

    [DataContract]
    public class EnumMember
    {
        [DataMember]
        public string Description { get; set; }
    
        [DataMember]
        public int Value { get; set; }
    
        public static List<EnumMember> ConvertToList<T>()
        {
            Type type = typeof(T);
    
            if (!type.IsEnum)
            {
                throw new ArgumentException("T must be of type enumeration.");
            }
    
            var members = new List<EnumMember>();
    
            foreach (string item in System.Enum.GetNames(type))
            {
                var enumType = System.Enum.Parse(type, item);
    
                members.Add(
                    new EnumMember() { Description = enumType.GetDescriptionValue(), Value = ((IConvertible)enumType).ToInt32(null) });
            }
    
            return members;
        }
    }
    

    这是从Enum获取描述的Extension方法 .

    public static string GetDescriptionValue<T>(this T source)
        {
            FieldInfo fileInfo = source.GetType().GetField(source.ToString());
            DescriptionAttribute[] attributes = (DescriptionAttribute[])fileInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);            
    
            if (attributes != null && attributes.Length > 0)
            {
                return attributes[0].Description;
            }
            else
            {
                return source.ToString();
            }
        }
    

    执行:

    return EnumMember.ConvertToList<YourType>();
    
  • 46

    我不知道在哪里获得此枚举扩展的一部分,但它来自stackoverflow . 对不起,我很抱歉!但我拿了这个并用Flags修改它的枚举 . 对于带有Flags的枚举,我这样做了:

    public static class Enum<T> where T : struct
      {
         private static readonly IEnumerable<T> All = Enum.GetValues(typeof (T)).Cast<T>();
         private static readonly Dictionary<int, T> Values = All.ToDictionary(k => Convert.ToInt32(k));
    
         public static T? CastOrNull(int value)
         {
            T foundValue;
            if (Values.TryGetValue(value, out foundValue))
            {
               return foundValue;
            }
    
            // For enums with Flags-Attribut.
            try
            {
               bool isFlag = typeof(T).GetCustomAttributes(typeof(FlagsAttribute), false).Length > 0;
               if (isFlag)
               {
                  int existingIntValue = 0;
    
                  foreach (T t in Enum.GetValues(typeof(T)))
                  {
                     if ((value & Convert.ToInt32(t)) > 0)
                     {
                        existingIntValue |= Convert.ToInt32(t);
                     }
                  }
                  if (existingIntValue == 0)
                  {
                     return null;
                  }
    
                  return (T)(Enum.Parse(typeof(T), existingIntValue.ToString(), true));
               }
            }
            catch (Exception)
            {
               return null;
            }
            return null;
         }
      }
    

    例:

    [Flags]
    public enum PetType
    {
      None = 0, Dog = 1, Cat = 2, Fish = 4, Bird = 8, Reptile = 16, Other = 32
    };
    
    integer values 
    1=Dog;
    13= Dog | Fish | Bird;
    96= Other;
    128= Null;
    
  • 206

    从字符串:( Enum.Parse已过期,使用Enum.TryParse)

    enum Importance
    {}
    
    Importance importance;
    
    if (Enum.TryParse(value, out importance))
    {
    }
    
  • 38

    它可以帮助您将任何输入数据转换为用户所需的 enum . 假设你有一个类似于下面的枚举,默认为 int . 请在枚举的第一个位置添加 Default 值 . 当找不到与输入值匹配时,在helpers方法中使用哪个 .

    public enum FriendType  
    {
        Default,
        Audio,
        Video,
        Image
    }
    
    public static class EnumHelper<T>
    {
        public static T ConvertToEnum(dynamic value)
        {
            var result = default(T);
            var tempType = 0;
    
            //see Note below
            if (value != null &&
                int.TryParse(value.ToString(), out  tempType) && 
                Enum.IsDefined(typeof(T), tempType))
            {
                result = (T)Enum.ToObject(typeof(T), tempType); 
            }
            return result;
        }
    }
    

    N.B: 这里我尝试将值解析为int,因为枚举是默认的 int 如果你定义这样的枚举 byte type .

    public enum MediaType : byte
    {
        Default,
        Audio,
        Video,
        Image
    }
    

    您需要更改辅助方法的解析

    int.TryParse(value.ToString(), out  tempType)
    

    byte.TryParse(value.ToString(), out tempType)

    我检查我的方法输入以下内容

    EnumHelper<FriendType>.ConvertToEnum(null);
    EnumHelper<FriendType>.ConvertToEnum("");
    EnumHelper<FriendType>.ConvertToEnum("-1");
    EnumHelper<FriendType>.ConvertToEnum("6");
    EnumHelper<FriendType>.ConvertToEnum("");
    EnumHelper<FriendType>.ConvertToEnum("2");
    EnumHelper<FriendType>.ConvertToEnum(-1);
    EnumHelper<FriendType>.ConvertToEnum(0);
    EnumHelper<FriendType>.ConvertToEnum(1);
    EnumHelper<FriendType>.ConvertToEnum(9);
    

    对不起我的英语不好

  • 23

    如果您有一个充当位掩码的整数并且可以表示[Flags]枚举中的一个或多个值,则可以使用此代码将各个标志值解析为列表:

    for (var flagIterator = 0x1; flagIterator <= 0x80000000; flagIterator <<= 1)
    {
        // Check to see if the current flag exists in the bit mask
        if ((intValue & flagIterator) != 0)
        {
            // If the current flag exists in the enumeration, then we can add that value to the list
            // if the enumeration has that flag defined
            if (Enum.IsDefined(typeof(MyEnum), flagIterator))
                ListOfEnumValues.Add((MyEnum)flagIterator);
        }
    }
    
  • 11

    以下是Enums的一个很好的实用程序类

    public static class EnumHelper
    {
        public static int[] ToIntArray<T>(T[] value)
        {
            int[] result = new int[value.Length];
            for (int i = 0; i < value.Length; i++)
                result[i] = Convert.ToInt32(value[i]);
            return result;
        }
    
        public static T[] FromIntArray<T>(int[] value) 
        {
            T[] result = new T[value.Length];
            for (int i = 0; i < value.Length; i++)
                result[i] = (T)Enum.ToObject(typeof(T),value[i]);
            return result;
        }
    
    
        internal static T Parse<T>(string value, T defaultValue)
        {
            if (Enum.IsDefined(typeof(T), value))
                return (T) Enum.Parse(typeof (T), value);
    
            int num;
            if(int.TryParse(value,out num))
            {
                if (Enum.IsDefined(typeof(T), num))
                    return (T)Enum.ToObject(typeof(T), num);
            }
    
            return defaultValue;
        }
    }
    
  • 58

    或者,使用扩展方法而不是单行:

    public static T ToEnum<T>(this string enumString)
    {
        return (T) Enum.Parse(typeof (T), enumString);
    }
    

    Usage:

    Color colorEnum = "Red".ToEnum<Color>();
    

    要么

    string color = "Red";
    var colorEnum = color.ToEnum<Color>();
    
  • 18

    我想要得到一个完整的答案,人们必须知道enums如何在.NET内部工作 .

    How stuff works

    .NET中的枚举是一组将一组值(字段)映射到基本类型的结构(默认为 int ) . 但是,您实际上可以选择枚举映射到的整数类型:

    public enum Foo : short
    

    在这种情况下,枚举被映射到 short 数据类型,这意味着它将作为short存储在内存中,并在您投射和使用它时表现为short .

    如果从IL的角度来看它,(normal,int)枚举如下所示:

    .class public auto ansi serializable sealed BarFlag extends System.Enum
    {
        .custom instance void System.FlagsAttribute::.ctor()
        .custom instance void ComVisibleAttribute::.ctor(bool) = { bool(true) }
    
        .field public static literal valuetype BarFlag AllFlags = int32(0x3fff)
        .field public static literal valuetype BarFlag Foo1 = int32(1)
        .field public static literal valuetype BarFlag Foo2 = int32(0x2000)
    
        // and so on for all flags or enum values
    
        .field public specialname rtspecialname int32 value__
    }
    

    这里应该引起注意的是 value__ 与枚举值分开存储 . 在上面的枚举 Foo 的情况下, value__ 的类型是int16 . 这基本上意味着您可以在枚举中存储您想要的任何内容, as long as the types match .

    在这一点上,我想指出 System.Enum 是一个值类型,这基本上意味着 BarFlag 将占用内存中的4个字节而 Foo 将占用2个 - 例如的大小基础类型(实际上比这更复杂,但是嘿......) .

    The answer

    因此,如果你有一个想要映射到枚举的整数,那么运行时只需做两件事:复制4个字节并将其命名为其他东西(枚举的名称) . 复制是隐式的,因为数据存储为值类型 - 这基本上意味着如果使用非托管代码,则可以简单地交换枚举和整数而无需复制数据 .

    为了使其安全,我认为这是最佳实践 know that the underlying types are the same or implicitly convertible 并确保存在枚举值(默认情况下不会检查它们!) .

    要查看其工作原理,请尝试以下代码:

    public enum MyEnum : int
    {
        Foo = 1,
        Bar = 2,
        Mek = 5
    }
    
    static void Main(string[] args)
    {
        var e1 = (MyEnum)5;
        var e2 = (MyEnum)6;
    
        Console.WriteLine("{0} {1}", e1, e2);
        Console.ReadLine();
    }
    

    请注意,转换为 e2 也有效!从上面的编译器角度来看,这是有道理的: value__ 字段只用5或6填充,当 Console.WriteLine 调用 ToString() 时, e1 的名称被解析,而 e2 的名称则没有 .

    如果这不是您的意图,请使用 Enum.IsDefined(typeof(MyEnum), 6) 检查您正在投射的值是否映射到定义的枚举 .

    另请注意,即使编译器实际检查了这一点,我也明确了枚举的基础类型 . 我这样做是为了确保我不会遇到任何意外 . 要查看这些惊喜,您可以使用以下代码(实际上我已经看到这在数据库代码中发生了很多):

    public enum MyEnum : short
    {
        Mek = 5
    }
    
    static void Main(string[] args)
    {
        var e1 = (MyEnum)32769; // will not compile, out of bounds for a short
    
        object o = 5;
        var e2 = (MyEnum)o;     // will throw at runtime, because o is of type int
    
        Console.WriteLine("{0} {1}", e1, e2);
        Console.ReadLine();
    }
    

相关问题