从C#中的枚举获取int值

我有一个名为Questions(复数)的类。在这个类中,有一个名为Question(单数)的枚举,看起来像这样。

public enum Question{Role = 2,ProjectFunding = 3,TotalEmployee = 4,NumberOfServers = 5,TopBusinessConcern = 6}

Questions类中,我有一个get(int foo)函数,它为foo返回一个Questions对象。有没有一种简单的方法可以从枚举中获取整数值,这样我就可以做类似于Questions.Get(Question.Role)的事情?

2103495 次浏览
Question question = Question.Role;int value = (int) question;

将导致value == 2

只需转换枚举,例如。

int something = (int) Question.Role;

上述方法适用于您在野外看到的绝大多数枚举,因为枚举的默认基础类型是int

但是,正如cecilphillip所指出的,枚举可以有不同的底层类型。如果枚举声明为uintlongulong,则应将其强制转换为枚举的类型;例如for

enum StarsInMilkyWay:long {Sun = 1, V645Centauri = 2 .. Wolf424B = 2147483649};

你应该使用

long something = (long)StarsInMilkyWay.Wolf424B;

这比你想象的要容易——枚举已经是一个int了。只需要提醒一下:

int y = (int)Question.Role;Console.WriteLine(y); // Prints 2

示例:

public enum EmpNo{Raj = 1,Rahul,Priyanka}

在后面的代码中获取枚举值:

int setempNo = (int)EmpNo.Raj; // This will give setempNo = 1

int setempNo = (int)EmpNo.Rahul; // This will give setempNo = 2

枚举将增加1,您可以设置起始值。如果您不设置起始值,它最初将被分配为0。

由于枚举可以是任何整数类型(byteintshort等),因此获取枚举的基础整数值的更健壮的方法是将GetTypeCode方法与Convert类结合使用:

enum Sides {Left, Right, Top, Bottom}Sides side = Sides.Bottom;
object val = Convert.ChangeType(side, side.GetTypeCode());Console.WriteLine(val);

无论基础整数类型如何,这都应该有效。

要确保枚举值存在,然后对其进行解析,您还可以执行以下操作。

// Fake Day of Weekstring strDOWFake = "SuperDay";
// Real Day of Weekstring 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() + ".");

如果你想为存储在变量中的枚举值获取一个整数,其类型为Question,例如在方法中使用,你可以简单地做到这一点,我在这个例子中写道:

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 parametervoid VeranderenTitel(Enum e){this.Text = Convert.ToInt32(e).ToString();}

这会将窗口标题更改为4,因为变量GeselecteerdTalen.Nederlands。如果我将其更改为Talen.Portugees并再次调用该方法,文本将更改为3。

将其声明为具有公共常量的静态类:

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;}

然后您可以将其引用为Question.Role,并且它始终计算为int或您定义的任何内容。

您可以通过对定义的枚举类型实现延拓法来做到这一点:

public static class MyExtensions{public static int getNumberValue(this Question questionThis){return (int)questionThis;}}

这简化了获取当前枚举值的int值:

Question question = Question.Role;int value = question.getNumberValue();

int value = Question.Role.getNumberValue();

我能想到的最简单的解决方案是像这样重载Get(int)方法:

[modifiers] Questions Get(Question q){return Get((int)q);}

其中[modifiers]通常可以与Get(int)方法相同。如果您无法编辑Questions类或出于某种原因不想编辑,您可以通过编写扩展来重载该方法:

public static class Extensions{public static Questions Get(this Questions qs, Question q){return qs.Get((int)q);}}

我最近在代码中不再使用枚举,而是使用带有受保护构造函数和预定义静态实例的类(感谢Roelof-C#确保有效枚举值-未来证明方法)。

有鉴于此,下面是我现在如何处理这个问题(包括隐式转换到/从int)。

public class Question{// Attributesprotected 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" valuespublic 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");
// Constructorsprotected Question(int index, string name){this.index = index;this.name = name;values.Add(index, this);}
// Easy int conversionpublic 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)}

这种方法的优点是您可以从枚举中获得所有内容,但是您的代码现在更加灵活,因此如果您需要根据Question的值执行不同的操作,您可以将逻辑放入Question本身(即以首选的OO方式),而不是在整个代码中放置大量case语句来处理每个场景。


注意:答案更新了2018-04-27,以利用C#6的特性;即声明表达式和lambda表达式主体定义。原始代码见修订历史。这样做的好处是使定义不那么冗长;这是对这个答案方法的主要抱怨之一。

在相关的说明中,如果你想从System.Enum中获取int值,那么在这里给出e

Enum e = Question.Role;

您可以使用:

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

最后两个很难看,我更喜欢第一个。

尝试这个而不是将enum转换为int:

public static class ReturnType{public static readonly int Success = 1;public static readonly int Duplicate = 2;public static readonly int Error = -1;}
public enum QuestionType{Role = 2,ProjectFunding = 3,TotalEmployee = 4,NumberOfServers = 5,TopBusinessConcern = 6}

…是一个很好的宣言。

你必须像这样将结果转换为int:

int Question = (int)QuestionType.Role

否则,类型仍然是QuestionType

这种严格程度是C#方式。

一种替代方法是使用类声明:

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}

声明起来不那么优雅,但你不需要将其转换为代码:

int Question = QuestionType.Role

或者,您可能会对Visual Basic感到更舒服,它在许多领域都能满足这种期望。

改用扩展方法:

public static class ExtensionMethods{public static int IntValue(this Enum argEnum){return Convert.ToInt32(argEnum);}}

用法稍微漂亮一点:

var intValue = Question.Role.IntValue();
int number = Question.Role.GetHashCode();

number应该具有值2

还有一种方法可以做到:

Console.WriteLine("Name: {0}, Value: {0:D}", Question.Role);

这将导致:

Name: Role, Value: 2

也许我错过了,但有人尝试过简单的泛型扩展方法吗?

这对我来说很棒。您可以通过这种方式避免API中的类型转换,但最终它会导致更改类型操作。这是编程罗斯林让编译器为您创建GetValue方法的好例子。

    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 integerreturn 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;}}

我最喜欢的带有int或更小的枚举的黑客:

GetHashCode();

对于enum

public enum Test{Min = Int32.MinValue,One = 1,Max = Int32.MaxValue,}

这个,

var values = Enum.GetValues(typeof(Test));
foreach (var val in values){Console.WriteLine(val.GetHashCode());Console.WriteLine(((int)val));Console.WriteLine(val);}

产出

one11max21474836472147483647min-2147483648-2147483648

免责声明:

它不适用于基于long的枚举。

我想建议“从枚举中获取'int'值”的示例是

public enum Sample{Book = 1,Pen = 2,Pencil = 3}
int answer = (int)Sample.Book;

现在答案将是1。

在Visual Basic中,它应该是:

Public Enum QuestionRole = 2ProjectFunding = 3TotalEmployee = 4NumberOfServers = 5TopBusinessConcern = 6End Enum
Private value As Integer = CInt(Question.Role)

以下是扩展方法

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;}

由于枚举可以用多个基本类型声明,因此转换任何枚举类型的泛型扩展方法可能很有用。

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;
public enum Suit : int{Spades = 0,Hearts = 1,Clubs = 2,Diamonds = 3}
Console.WriteLine((int)(Suit)Enum.Parse(typeof(Suit), "Clubs"));
// From intConsole.WriteLine((Suit)1);
// From a number you can alsoConsole.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);}

我想出了这个包含当前语言特性的扩展方法。通过使用动态,我不需要使其成为通用方法并指定保持调用更简单和一致的类型:

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;}

用途:

Question question = Question.Role;int value = question.GetHashCode();

这将导致value == 2

只有当枚举适合int时,这才是正确的。

您应该使用类型铸造,因为我们可以在任何其他语言中使用。

如果你的enum是这样的

public enum Question{Role = 2,ProjectFunding = 3,TotalEmployee = 4,NumberOfServers = 5,TopBusinessConcern = 6}

你需要投到一个int,然后这样做-

Question q = Question.Role;..........................int something = (int) q;

重新

在C#中,有两种类型的强制转换:

  • 隐式转换(自动-将较小的类型转换为较大的类型大小,例如-

char->int->long->float->double

  • 显式铸造(手动-将较大的类型转换为较小的类型,例如-

double->float->long->int->char

更多信息可以在这里中找到。

将为您提供包含枚举的所有整数值的列表:

List enumValue=Enum. GetValue(typeof(EnumClass)). Cast(). ToList();

public enum ViewType{List = 1,Table = 2,};            
// You can use the Enum type as a parameter, so any enumeration from any enumerator// cshtml// using proyects.Helpers// @if (Model.ViewType== (int)<variable>.List )