2141

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

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

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

4

29 回答 29

2722

只需投射枚举,例如

int something = (int) Question.Role;

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

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

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

你应该使用

long something = (long)StarsInMilkyWay.Wolf424B;
于 2009-06-03T06:49:18.553 回答
349

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

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

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

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

于 2010-07-09T14:54:16.767 回答
213

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

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,并且它始终评估为 anint或您将其定义为的任何内容。

于 2012-06-15T19:28:37.827 回答
103

在相关说明中,如果您想从中获取intSystem.Enum,则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);

最后两个简直丑陋。我更喜欢第一个。

于 2013-12-01T08:47:44.817 回答
100
Question question = Question.Role;
int value = (int) question;

将导致value == 2.

于 2009-06-03T06:48:16.030 回答
44

它比您想象的要容易 - 枚举已经是 int。只是需要提醒一下:

int y = (int)Question.Role;
Console.WriteLine(y); // Prints 2
于 2009-06-03T06:51:59.360 回答
43

例子:

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。

于 2009-09-25T10:43:14.107 回答
31

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

鉴于此,下面是我现在处理这个问题的方式(包括隐式转换到/从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 中)时尚)而不是在整个代码中放置大量案例语句来处理每种情况。


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

于 2013-03-30T01:08:55.633 回答
22

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

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

于 2012-06-10T22:58:20.227 回答
18

另一种方法:

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

这将导致:

Name: Role, Value: 2
于 2014-09-19T05:42:30.490 回答
17

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

// 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() + ".");
于 2011-07-22T20:56:19.087 回答
14

改用扩展方法:

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

而且用法稍微漂亮一点:

var intValue = Question.Role.IntValue();
于 2014-04-21T02:51:42.283 回答
14

也许我错过了,但有没有人尝试过一个简单的通用扩展方法?

这对我很有用。您可以通过这种方式避免 API 中的类型转换,但最终会导致更改类型操作。这是对Roslyn进行编程以让编译器为您创建 GetValue<T> 方法的一个很好的案例。

    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;
    }
}
于 2014-09-27T01:30:47.993 回答
13
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 感觉更舒服,它在许多领域都满足了这种类型的期望。

于 2014-03-31T16:35:56.253 回答
12
int number = Question.Role.GetHashCode();

number应该有价值2

于 2014-09-18T22:53:47.663 回答
12

采用:

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

这将导致value == 2.

仅当枚举适合于int.

于 2019-08-12T03:27:28.350 回答
11

您可以通过为定义的枚举类型实现扩展方法来做到这一点:

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();
于 2012-12-09T22:09:56.603 回答
8
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 a 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);
}
于 2018-07-27T06:29:29.937 回答
6

由于可以使用多种原始类型声明枚举,因此转换任何枚举类型的通用扩展方法可能很有用。

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;
于 2017-12-06T05:14:37.847 回答
4

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

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

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

public static class Extensions
{
    public static Questions Get(this Questions qs, Question q)
    {
        return qs.Get((int)q);
    }
}
于 2013-01-28T13:52:52.347 回答
4

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

public static class ReturnType
{
    public static readonly int Success = 1;
    public static readonly int Duplicate = 2;
    public static readonly int Error = -1;        
}
于 2014-01-14T20:28:07.547 回答
4

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

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

免责声明:

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

于 2015-06-26T16:51:09.400 回答
4

以下是扩展方法

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;
}
于 2016-12-16T06:58:06.100 回答
3

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

public enum Sample
{
    Book = 1, 
    Pen = 2, 
    Pencil = 3
}

int answer = (int)Sample.Book;

现在答案将是 1。

于 2015-08-03T07:12:01.750 回答
3

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

如果你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

更多可以在这里找到。

于 2020-09-23T06:54:32.937 回答
0

在 Visual Basic 中,它应该是:

Public Enum Question
    Role = 2
    ProjectFunding = 3
    TotalEmployee = 4
    NumberOfServers = 5
    TopBusinessConcern = 6
End Enum

Private value As Integer = CInt(Question.Role)
于 2016-04-12T07:09:30.300 回答
0

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

列出 enumValues = Enum.GetValues(typeof(EnumClass)).Cast().ToList();

于 2021-01-12T02:14:04.690 回答
0
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 )
于 2021-06-10T16:09:43.990 回答
-2

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

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;
    }
于 2019-03-02T17:55:26.353 回答