首页 文章

从C#中的枚举中获取int值

提问于
浏览
1463

我有一个名为 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) 这样的事情?

25 回答

  • -14

    它比你想象的容易 - 枚举已经是一个整数 . 它只需要提醒:

    int y = (int)Question.Role;
    Console.WriteLine(y); // prints 2
    
  • 16

    例:

    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 .

  • 35

    我最近在代码中转而使用枚举,转而使用带有受保护构造函数和预定义静态实例的类(感谢Roelof - C# Ensure Valid Enum Values - Futureproof Method) .

    鉴于此,现在在's how I'下方处理此问题(包括隐式转换为/来自 int ) .

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

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


    注意:答案更新2018-04-27以利用C#6功能;即声明表达式和lambda表达式主体定义 . 有关原始代码,请参阅revision history . 这样做的好处是使定义不那么冗长;这是对这个答案方法的主要抱怨之一 .

  • 25
    int number = Question.Role.GetHashCode();
    

    number 应该具有值 2 .

  • 74
    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感到更舒服,因为Visual Basic可以满足许多领域的这种期望 .

  • 1
    Question question = Question.Role;
    int value = (int) question;
    

    将导致 value == 2 .

  • 14

    试试这个 :

    int value = YourEnum.ToString("D");
    
  • 58

    在相关的说明中,如果要从 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);
    

    最后两个是丑陋的 . 我更喜欢第一个 .

  • 3

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

    public static class ReturnType
    {
        public static readonly int Success = 1;
        public static readonly int Duplicate = 2;
        public static readonly int Error = -1;        
    }
    
  • 10

    也许我错过了它,但有人试过一个简单的通用扩展方法 . 这对我很有用 . 您可以通过这种方式避免API中的类型转换,但最终会导致更改类型操作 . 这是编程Roselyn以使编译器为您创建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 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;
        }
    }
    
  • 9
    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);
    }
    
  • 1

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

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

    无论底层整数类型如何,这都应该有效 .

  • 11

    刚刚施放枚举,例如

    int something = (int) Question.Role;
    

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

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

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

    你应该使用

    long something = (long)StarsInMilkyWay.Wolf424B;
    
  • 3

    如果你想得到一个存储在变量中的枚举值的整数,如果类型为 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 parameter
    void VeranderenTitel(Enum e)
    {
        this.Text = Convert.ToInt32(e).ToString();
    }
    

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

    我很难在互联网上找到这个简单的解决方案而我找不到它,所以我正在测试一些东西并发现了这一点 . 希望这可以帮助 . ;)

  • 1905

    如何改为扩展方法:

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

    而且用法稍微漂亮一些:

    var intValue = Question.Role.IntValue();
    
  • 251

    在Vb . 它应该是

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

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

    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 或你定义的任何东西 .

  • 3

    还有一种方法:

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

    将导致:

    Name: Role, Value: 2
    
  • 19

    我能想到的最简单的解决方案是重载 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);
        }
    }
    
  • 9

    以下是扩展方法

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

    我想建议'从enum获得'int'值的例子是,'

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

    现在的答案是1 .

    我希望这可能对某人有所帮助 .

  • 2

    我最喜欢使用int或更小的枚举:

    GetHashCode();
    

    对于一个枚举

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

    输出

    one
    1
    1  
    max
    2147483647
    2147483647    
    min
    -2147483648
    -2147483648
    

    Disclaimer: 对基于long的枚举不起作用

  • 1

    要确保存在枚举值,然后解析它,您还可以执行以下操作 .

    // 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() + ".");
    

    我希望这有帮助 .

  • 11

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

    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;
    
  • 6

    您可以通过对定义的枚举类型实现 Extension Method 来执行此操作:

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

相关问题