从 C#中的枚举获取 int 值

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

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

Questions类中,我有一个get(int foo)函数,该函数返回该fooQuestions对象。有没有一种简单的方法可以从枚举中获取整数值,因此我可以执行Questions.Get(Question.Role)

答案

只是枚举枚举,例如

int something = (int) Question.Role;

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

但是,正如cecilphillip指出的那样,枚举可以具有不同的基础类型。如果将枚举声明为uintlongulong ,则应将其强制转换为枚举类型;例如

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

你应该使用

long something = (long)StarsInMilkyWay.Wolf424B;

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

enum Sides {
    Left, Right, Top, Bottom
}
Sides side = Sides.Bottom;

object val = Convert.ChangeType(side, side.GetTypeCode());
Console.WriteLine(val);

无论基础整数类型如何,这都应该起作用。

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

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或您定义为int任何值。

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

将导致value == 2

与此相关的是,如果要从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);

最后两个很丑陋。我喜欢第一个。

比您想象的要容易 - 枚举已经是一个 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。

最近,我不再使用代码中的枚举,而是改为使用具有受保护的构造函数和预定义的静态实例的类(这要归功于 Roelof- C#确保有效的枚举值 - Futureproof 方法 )。

鉴于此,以下是我现在如何解决此问题的方法(包括隐式转换为int或从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 表达式主体定义。有关原始代码,请参见修订历史记录 。这样做的好处是使定义不再那么冗长。这是对该答案方法的主要抱怨之一。

如果您想获取存储在变量中的枚举值的整数(类型为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();
}

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

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

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