Get int value from enum in C#
我有一个叫
1 2 3 4 5 6 7 8 | public enum Question { Role = 2, ProjectFunding = 3, TotalEmployee = 4, NumberOfServers = 5, TopBusinessConcern = 6 } |
在
只需强制转换枚举,例如
1 | int something = (int) Question.Role; |
上面的内容适用于您在野外看到的绝大多数枚举,因为枚举的默认底层类型是
然而,正如Cecilphillip指出的,枚举可以有不同的底层类型。如果枚举声明为
1 | enum StarsInMilkyWay:long {Sun = 1, V645Centauri = 2 .. Wolf424B = 2147483649}; |
你应该使用
1 | long something = (long)StarsInMilkyWay.Wolf424B; |
由于枚举可以是任何整数类型(
1 2 3 4 5 6 7 | enum Sides { Left, Right, Top, Bottom } Sides side = Sides.Bottom; object val = Convert.ChangeType(side, side.GetTypeCode()); Console.WriteLine(val); |
不管底层的整型是什么,这都应该有效。
将其声明为具有公共常量的静态类:
1 2 3 4 5 6 7 8 | public static class Question { public const int Role = 2; public const int ProjectFunding = 3; public const int TotalEmployee = 4; public const int NumberOfServers = 5; public const int TopBusinessConcern = 6; } |
然后你可以引用它作为
1 2 | Question question = Question.Role; int value = (int) question; |
会导致
在相关注释中,如果您想从
1 | Enum e = Question.Role; |
你可以使用:
1 2 3 4 | int i = Convert.ToInt32(e); int i = (int)(object)e; int i = (int)Enum.Parse(e.GetType(), e.ToString()); int i = (int)Enum.ToObject(e.GetType(), e); |
最后两个很难看。我喜欢第一个。
这比你想象的要简单-枚举已经是int了。只需要提醒一下:
1 2 | int y = (int)Question.Role; Console.WriteLine(y); // prints 2 |
例子:
1 2 3 4 5 6 | public Enum EmpNo { Raj = 1, Rahul, Priyanka } |
在代码后面获取枚举值:
1 | int setempNo = (int)EmpNo.Raj; //This will give setempNo = 1 |
或
1 | int setempNo = (int)EmpNo.Rahul; //This will give setempNo = 2 |
枚举将增加1,您可以设置起始值。如果不设置起始值,则最初会将其指定为0。
最近,我不再在代码中使用枚举,而是改用带有受保护的构造函数和预定义静态实例的类(这要归功于roelof-c确保有效的枚举值-futureProof方法)。
有鉴于此,下面是我现在处理这个问题的方法(包括隐式转换到/从
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | public class Question { // Attributes protected int index; protected string name; // Go with a dictionary to enforce unique index //protected static readonly ICollection<Question> values = new Collection<Question>(); protected static readonly IDictionary<int,Question> values = new Dictionary<int,Question>(); // Define the"enum" values public static readonly Question Role = new Question(2,"Role"); public static readonly Question ProjectFunding = new Question(3,"Project Funding"); public static readonly Question TotalEmployee = new Question(4,"Total Employee"); public static readonly Question NumberOfServers = new Question(5,"Number of Servers"); public static readonly Question TopBusinessConcern = new Question(6,"Top Business Concern"); // Constructors protected Question(int index, string name) { this.index = index; this.name = name; values.Add(index, this); } // Easy int conversion public static implicit operator int(Question question) => question.index; //nb: if question is null this will return a null pointer exception public static implicit operator Question(int index) => values.TryGetValue(index, out var question) ? question : null; // Easy string conversion (also update ToString for the same effect) public override string ToString() => this.name; public static implicit operator string(Question question) => question?.ToString(); public static implicit operator Question(string name) => name == null ? null : values.Values.FirstOrDefault(item => name.Equals(item.name, StringComparison.CurrentCultureIgnoreCase)); // If you specifically want a Get(int x) function (though not required given the implicit converstion) public Question Get(int foo) => foo; //(implicit conversion will take care of the conversion for you) } |
这种方法的优点是,您可以从枚举中获得所需的一切,但是您的代码现在更加灵活,因此,如果您需要根据EDOCX1的值(10)执行不同的操作,那么您可以将逻辑放入
注意:答案更新了2018-04-27,以利用C 6功能,即声明表达式和lambda表达式体定义。原始代码见修订历史。这样做的好处是让这个定义不那么冗长;这是关于这个答案方法的主要抱怨之一。
如果要为存储在变量中的枚举值获取一个整数,则类型为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | enum Talen { Engels = 1, Italiaans = 2, Portugees = 3, Nederlands = 4, Duits = 5, Dens = 6 } Talen Geselecteerd; public void Form1() { InitializeComponent() Geselecteerd = Talen.Nederlands; } // You can use the Enum type as a parameter, so any enumeration from any enumerator can be used as parameter void VeranderenTitel(Enum e) { this.Text = Convert.ToInt32(e).ToString(); } |
这会将窗口标题更改为4,因为变量
我很难在互联网上找到这个简单的解决方案,我找不到它,所以我在测试一些东西,然后发现了这个问题。希望这有帮助。;)
为了确保枚举值存在,然后分析它,您还可以执行以下操作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | // Fake Day of Week string strDOWFake ="SuperDay"; // Real Day of Week string strDOWReal ="Friday"; // Will hold which ever is the real DOW. DayOfWeek enmDOW; // See if fake DOW is defined in the DayOfWeek enumeration. if (Enum.IsDefined(typeof(DayOfWeek), strDOWFake)) { // This will never be reached since"SuperDay" // doesn't exist in the DayOfWeek enumeration. enmDOW = (DayOfWeek)Enum.Parse(typeof(DayOfWeek), strDOWFake); } // See if real DOW is defined in the DayOfWeek enumeration. else if (Enum.IsDefined(typeof(DayOfWeek), strDOWReal)) { // This will parse the string into it's corresponding DOW enum object. enmDOW = (DayOfWeek)Enum.Parse(typeof(DayOfWeek), strDOWReal); } // Can now use the DOW enum object. Console.Write("Today is" + enmDOW.ToString() +"."); |
我希望这有帮助。
也许我错过了,但有人尝试过一个简单的通用扩展方法吗?这对我很有用。这样可以避免API中的类型转换,但最终会导致更改类型操作。对于编程Roselyn来说,让编译器为您生成getValue方法是一个很好的例子。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | public static void Main() { int test = MyCSharpWrapperMethod(TestEnum.Test1); Debug.Assert(test == 1); } public static int MyCSharpWrapperMethod(TestEnum customFlag) { return MyCPlusPlusMethod(customFlag.GetValue<int>()); } public static int MyCPlusPlusMethod(int customFlag) { //Pretend you made a PInvoke or COM+ call to C++ method that require an integer return customFlag; } public enum TestEnum { Test1 = 1, Test2 = 2, Test3 = 3 } } public static class EnumExtensions { public static T GetValue<T>(this Enum enumeration) { T result = default(T); try { result = (T)Convert.ChangeType(enumeration, typeof(T)); } catch (Exception ex) { Debug.Assert(false); Debug.WriteLine(ex); } return result; } } |
另一种方法是:
1 | Console.WriteLine("Name: {0}, Value: {0:D}", Question.Role); |
将导致:
1 | Name: Role, Value: 2 |
1 2 3 4 5 6 7 8 | public enum QuestionType { Role = 2, ProjectFunding = 3, TotalEmployee = 4, NumberOfServers = 5, TopBusinessConcern = 6 } |
…是一个很好的声明。
您必须将结果强制转换为int,如下所示:
1 | int Question = (int)QuestionType.Role |
否则,类型仍然是
这种严格程度是C方式。
另一种选择是改用类声明:
1 2 3 4 5 6 7 8 | public class QuestionType { public static int Role = 2, public static int ProjectFunding = 3, public static int TotalEmployee = 4, public static int NumberOfServers = 5, public static int TopBusinessConcern = 6 } |
声明不太优雅,但您不需要将其强制转换为代码:
1 | int Question = QuestionType.Role |
或者,您可能会对VisualBasic感到更舒服,它在许多领域都能满足这种期望。
1 | int number = Question.Role.GetHashCode(); |
可以通过对定义的枚举类型实现扩展方法来完成此操作:
1 2 3 4 5 6 7 | public static class MyExtensions { public static int getNumberValue(this Question questionThis) { return (int)questionThis; } } |
这简化了获取当前枚举值的int值:
1 2 | Question question = Question.Role; int value = question.getNumberValue(); |
或
1 | int value = Question.Role.getNumberValue(); |
改为扩展方法如何:
1 2 3 4 5 6 7 | public static class ExtensionMethods { public static int IntValue(this Enum argEnum) { return Convert.ToInt32(argEnum); } } |
而且使用起来稍微漂亮一点:
1 | var intValue = Question.Role.IntValue(); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | public enum Suit : int { Spades = 0, Hearts = 1, Clubs = 2, Diamonds = 3 } Console.WriteLine((int)(Suit)Enum.Parse(typeof(Suit),"Clubs")); //from int Console.WriteLine((Suit)1); //From number you can also Console.WriteLine((Suit)Enum.ToObject(typeof(Suit), 1)); if (typeof(Suit).IsEnumDefined("Spades")) { var res = (int)(Suit)Enum.Parse(typeof(Suit),"Spades"); Console.Out.WriteLine("{0}", res); } |
我的fav-hack使用int或更小的枚举:
1 | GetHashCode(); |
为枚举
1 2 3 4 5 6 | public enum Test { Min = Int32.MinValue, One = 1, Max = Int32.MaxValue, } |
这
1 2 3 4 5 6 7 8 | var values = Enum.GetValues(typeof(Test)); foreach (var val in values) { Console.WriteLine(val.GetHashCode()); Console.WriteLine(((int)val)); Console.WriteLine(val); } |
输出
1 2 3 4 5 6 7 8 9 | one 1 1 max 2147483647 2147483647 min -2147483648 -2147483648 |
免责声明:不适用于基于long的枚举
下面是扩展方法
1 2 3 4 5 6 7 8 9 |
由于枚举可以用多个基元类型声明,因此可以使用通用扩展方法来强制转换任何枚举类型。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | enum Box { HEIGHT, WIDTH, DEPTH } public static void UseEnum() { int height = Box.HEIGHT.GetEnumValue<int>(); int width = Box.WIDTH.GetEnumValue<int>(); int depth = Box.DEPTH.GetEnumValue<int>(); } public static T GetEnumValue<T>(this object e) => (T)e; |
我建议"从枚举中获取"int"值的示例是,"
1 2 3 4 | public enum Sample {Book =1, Pen=2, Pencil =3} int answer = (int)Sample.Book; |
现在答案是1。
我希望这能帮助别人。
尝试此方法,而不是将枚举转换为int:
1 2 3 4 5 6 | public static class ReturnType { public static readonly int Success = 1; public static readonly int Duplicate = 2; public static readonly int Error = -1; } |
在VB中。应该是
1 2 3 4 5 6 7 8 9 | Public Enum Question Role = 2 ProjectFunding = 3 TotalEmployee = 4 NumberOfServers = 5 TopBusinessConcern = 6 End Enum Private value As Integer = CInt(Question.Role) |
我能想到的最简单的解决方案是重载这样的
1 2 3 4 | [modifiers] Questions Get(Question q) { return Get((int)q); } |
其中,
1 2 3 4 5 6 7 | public static class Extensions { public static Questions Get(this Questions qs, Question q) { return qs.Get((int)q); } } |
我有点晚了,但我想出了包括当前语言功能的扩展方法。通过使用dynamic,我不需要将其设置为泛型方法,并指定保持调用简单和一致的类型。如果我做错了请告诉我:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | public static class EnumEx { public static dynamic Value(this Enum e) { switch (e.GetTypeCode()) { case TypeCode.Byte: { return (byte) (IConvertible) e; } case TypeCode.Int16: { return (short) (IConvertible) e; } case TypeCode.Int32: { return (int) (IConvertible) e; } case TypeCode.Int64: { return (long) (IConvertible) e; } case TypeCode.UInt16: { return (ushort) (IConvertible) e; } case TypeCode.UInt32: { return (uint) (IConvertible) e; } case TypeCode.UInt64: { return (ulong) (IConvertible) e; } case TypeCode.SByte: { return (sbyte) (IConvertible) e; } } return 0; } |
试试这个:
1 | int value = YourEnum.ToString("D"); |