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

Get int value from enum in C#

提问人:jim 提问时间:6/3/2009 最后编辑:jim 更新时间:6/29/2023 访问量:2282799

问:

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

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

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

C# 枚举 强制转换 int

评论

47赞 nawfal 6/9/2013
反之亦然:cast-int-to-enum-in-c-sharp
16赞 Joe 2/7/2017
我知道我来晚了,但不是像你可以定义的那样定义你的方法,然后在方法中进行强制转换,你可以把你的方法称为get(int foo)get(Question foo)Questions.Get(Question.Role)
1赞 گلی 7/18/2021
试试这个: int int_Choose = (int) Question.Role;
0赞 John Alexiou 8/27/2023
了解您对枚举类型的处理方式

答:

112赞 jerryjvl 6/3/2009 #1
Question question = Question.Role;
int value = (int) question;

将导致 .value == 2

评论

4赞 jim 6/3/2009
所以像这样的东西 Questions.Get(Convert.ToInt16(Question.Applications))
10赞 Marc Gravell 6/3/2009
您可以简单地向任一方向投射;唯一需要注意的是,枚举不会强制执行任何内容(枚举值可以是 288,即使该数字不存在 Question)
3赞 Guffa 6/3/2009
@jim:不,只需转换值:Questions.Get((int)Question.Applications);
2938赞 Tetraneutron 6/3/2009 #2

只需转换枚举,例如

int something = (int) Question.Role;

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

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

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

你应该使用

long something = (long)StarsInMilkyWay.Wolf424B;

评论

28赞 Jaider 6/29/2012
@Harry这不是真的。您可以在不强制转换的情况下创建枚举,这不是必需的。而且我只在特殊情况下分配数字,大多数时候,我将其保留为默认值。但你可以做到并看到这是平等的。enum Test { Item = 1 }1 == (int)Test.Item
52赞 Sinthia V 7/27/2012
@Jaider 那是演员阵容!() 是显式强制转换运算符。(int)Test.Item
58赞 Paul Ridgway 8/18/2012
@Sinthia V 他说你可以在没有铸造的情况下创建它,这是正确的
10赞 quaylar 10/30/2013
如果 的基础类型不是 ,但此强制转换将截断 s 整数值!enum QuestionintlongRole
4赞 percebus 8/19/2015
当您接受 an 作为参数时,您知道只能获得固定数量的可能整数值。另一方面,如果仅取 ,则必须验证它是否在可接受的值范围内,从而使代码复杂化。你总是可以覆盖你的签名,比如 ''' public void MyMethod(int x) { // 用 x 做一些事情 } public void MyMethod(Enum x) { this.MyMethod((int) x);} ````Enumintint
49赞 Michael Petrotta 6/3/2009 #3

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

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

评论

17赞 mqp 6/3/2009
吹毛求疵:这个枚举已经是一个 int。其他枚举可能是不同的类型 -- 尝试“枚举 SmallEnum : byte { A, B, C }”
11赞 Michael Petrotta 6/3/2009
绝对正确。C# 参考:“每个枚举类型都有一个基础类型,该类型可以是除 char 之外的任何整型类型。
63赞 sooraj 9/25/2009 #4

例:

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。

评论

1赞 Timothy Gonzalez 11/15/2016
Raj 的东西也可以是 Rahul 或 Priyanka 吗?您的值发生冲突,应该加倍才能唯一,例如 0、1、2、4、8 等。这是我对枚举的核心关注点。
1赞 derHugo 10/11/2019
@TimothyGonzalez实际上,如果您没有明确指定枚举的值,则只会将其数为 1;)
1赞 Timothy Gonzalez 10/11/2019
@derHugo这取决于您假设数值是以 10 为基数还是以 2 为基数。
4赞 derHugo 10/11/2019
@TimothyGonzalez好吧,没有什么可假设的......我刚刚指出,默认情况下,除非您明确定义否则,它们只会计数1int
378赞 cecilphillip 7/9/2010 #5

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

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

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

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

评论

49赞 aboy021 7/6/2011
在处理泛型类型时,这种技术向我证明了它的价值,其中 T:enum(实际上是 T:struct,IConvertible,但那是另一回事)。
4赞 Mark Lakata 11/9/2012
您将如何修改它以打印出 side 的十六进制值?此示例显示十进制值。问题是这是类型,所以你需要拆箱,它变得比我想要的更混乱。varobject
3赞 theLaw 6/10/2014
如果要转换为 int try(如果是枚举 Sides : int) [...] object val = Convert.ChangeType(side, typeof(int));[...]
6赞 NickG 3/24/2015
@TimAbell 我只能说,我们发现动态编译的 aspx 页面(您必须将.cs文件部署到实时服务器)以不同的方式为每个值分配整数。这意味着在一台机器上序列化对象,在另一台机器上使用不同的值进行反序列化,并有效地被损坏(导致数小时的混乱)。我们向 MS 提出了这个问题,我似乎记得他们说,当跨不同的框架版本构建时,不能保证自动生成的整数是相同的。
12赞 NickG 3/24/2015
@TimAbell 在另一个场合,开发人员删除了过时/未使用的枚举值,导致序列中的所有其他值都消失了 1。因此,我们的编码标准现在要求始终显式指定 ID,否则添加/删除甚至自动格式化代码(例如按字母顺序排序)将更改所有导致数据损坏的值。我强烈建议任何人明确指定所有枚举整数。如果它们与外部(数据库)存储的值相关,则这一点非常重要。
17赞 Nathon 7/23/2011 #6

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

// 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() + ".");
23赞 Mathijs Van Der Slagt 6/11/2012 #7

如果你想获取存储在变量中的枚举值的整数,其类型将是 ,例如在方法中使用,你可以简单地执行我在这个例子中写的: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,因为变量是 .如果我将其更改为并再次调用该方法,则文本将更改为 3。GeselecteerdTalen.NederlandsTalen.Portugees

评论

0赞 Greg 2/5/2019
不幸的是,这种方法使用得越多,性能就越差。我在我的一些代码中尝试了它,随着时间的推移,我的应用程序变得越来越慢,CPU 使用率越来越低。这意味着线程正在等待某些东西 - 我假设某种垃圾回收,可能是由于将枚举参数装箱到 ToInt32()。通过切换到简单的 int.Parse(),我能够完全消除这种糟糕的性能,并且无论代码运行多长时间,性能都保持不变。
227赞 PablosBicicleta 6/16/2012 #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;
}

然后你可以把它引用为 ,它总是计算为你定义它的任何内容。Question.Roleint

评论

38赞 CAD bloke 5/16/2013
我会使用,因为常量被编译成它们的硬值。查看 stackoverflow.com/a/755693/492static readonly int
112赞 gchbib 4/13/2014
此解决方案实际上并不提供强类型枚举的真正好处。例如,如果我只想将 GameState-enum-parameter 传递给特定方法,编译器就不应该允许我将任何 int 变量作为参数传递。
16赞 blockloop 8/15/2014
@CADBloke这正是您使用而不是的原因,因为每次比较时,您都在进行方法调用以获取变量的值,而使用 a 时,您直接比较两种值类型。conststatic readonlystatic readonlyconst
5赞 CAD bloke 8/15/2014
@brettof86 是的,const 会更快,如果编译限制永远不会成为问题,那么一切都很好。
6赞 CAD bloke 4/23/2015
@Zack我没有很好地解释这一点,我的意思是,在编译该值时,该值是硬编码的,因此对该值的任何更改都需要重新编译使用它的所有程序集。我倾向于同意你关于用法的看法,因为更改值会产生深远的影响。compilation limitation
12赞 Bronek 12/10/2012 #9

为此,可以对定义的枚举类型实现扩展方法

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

评论

7赞 Benjamin Gruenbaum 12/10/2012
Bronek,你所做的是通过一个(非通用的顺便说一句)扩展方法编造出无信息的语法,这实际上需要更长的时间来编写。我看不出它比 Tetraneutron 的原始解决方案更好。让我们不要把它变成聊天,stackoverflow 总是欢迎帮助,这里的每个人都在这里提供帮助。请把我的评论当作建设性的批评。
3赞 Bronek 12/10/2012
本杰明,首先,你为什么删除我的评论?我不明白你的决定——也许社区中的其他人会同意我的评论。其次,我的解决方案包装了 Tetraneutron 的解决方案,准确地说,它更容易,写得更少,因为 IntelliSense.So 提出了一种扩展方法,我认为您的决定不公正且不具有代表性。我在 Stack 上看到很多类似的答案,没关系。无论如何,我使用我的解决方案,也许将来有些人会选择我的解决方案,但这些缺点使它更难找到。最重要的是,它是正确的,而不是复制的。
4赞 Benjamin Gruenbaum 8/7/2013
@Bronek 如果你不给我打电话,我没有得到你回复的迹象。我没有删除你的评论,我没有能力或不想这样做。可能有一个模组过来并删除了它 - 欢迎您标记它以引起版主的注意,并询问原因或更好的是 - 在 Meta Stack Overflow 上提问。从编程的角度来看,我对你的解决方案有一个看法,这完全符合我的权利 - 这就是评论的开始,没有必要把它当成个人的。
5赞 Grx70 1/28/2013 #10

我能想到的最简单的解决方案是像这样重载方法: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);
    }
}
35赞 JohnLBevan 3/30/2013 #11

我最近从在代码中使用枚举转变为使用具有受保护构造函数和预定义静态实例的类(感谢 Roelof - C# 确保有效的枚举值 - Futureproof 方法)。

有鉴于此,以下是我现在如何处理这个问题(包括隐式转换为/从)。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)
}

这种方法的优点是你可以从枚举中获得你所拥有的一切,但你的代码现在更加灵活,所以如果你需要根据 的值执行不同的操作,你可以把逻辑放进去(即以首选的 OO 方式),而不是在整个代码中放大量的 case 语句来处理每个场景。QuestionQuestion


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

评论

2赞 user692942 8/2/2013
我想这是显式强制转换和您必须编写的代码来规避它之间的权衡。仍然喜欢实现,只是希望它不要那么冗长。+1
4赞 James Haug 9/9/2016
我使用了几种不同类型的类,其结构与此类似。我发现,当试图遵循“以后不要让我成为白痴”的方法时,它们会创造奇迹。
0赞 JohnLBevan 6/2/2022
喜欢这种方法的人可能会对 github.com/ardalis/SmartEnum 感兴趣;一个泛型类,旨在为以上述方式定义的类提供类似枚举的功能。
123赞 nawfal 12/1/2013 #12

与此相关的是,如果要从 中获取值,则此处给出:intSystem.Enume

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

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

评论

4赞 Johan B 6/16/2019
不过,第二个是最快的。
2赞 Sollace 10/14/2019
作为一个习惯于在 Minecraft 模组中使用 Mixins 的人,第二个似乎是显而易见的赢家。
2赞 andreyk2 Hohlov 8/17/2020
第五个选项(正如大多数答案所说)是:int i = (int)e;(不先投射到对象)
5赞 nawfal 8/18/2020
@andreyk2HohlovCannot convert type 'System.Enum' to 'int'
4赞 Nalan Madheswaran 1/15/2014 #13

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

public static class ReturnType
{
    public static readonly int Success = 1;
    public static readonly int Duplicate = 2;
    public static readonly int Error = -1;        
}
15赞 WonderWorker 4/1/2014 #14
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 感到更满意,因为它在许多方面都满足了这种类型的期望。

22赞 SixOThree 4/21/2014 #15

请改用扩展方法:

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

而且用法稍微漂亮一些:

var intValue = Question.Role.IntValue();
13赞 JaimeArmenta 9/19/2014 #16
int number = Question.Role.GetHashCode();

number应具有值。2

评论

0赞 ThanhLD 11/9/2018
GetHashCode 是从枚举通用掩码获取值的一种方法
0赞 AnorZaken 2/18/2020
请注意,这仅是 *、、、 和 ** 的“合法”。其他类型的 GetHashCode 会修改该值,例如执行一些位移和 xors。(* 1 / 0,**当然转换为 int)。但总而言之,除非是你自己的私人代码,否则不要这样做。boolbyteushortintuint
19赞 plavozont 9/19/2014 #17

还有一种方法:

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

这将导致:

Name: Role, Value: 2

评论

1赞 Andrew Chaa 10/29/2020
这是我的用例的最佳解决方案,因为我的枚举是 int 和 long 值的混合
14赞 Doug 9/27/2014 #18

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

这对我来说很有效。您可以通过这种方式避免 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;
    }
}

评论

0赞 Tim Keating 11/12/2014
可能是因为执行 (int)customFlag 时,到处都是打字次数较少,并且或多或少地做同样的事情?
0赞 Peter Mortensen 12/9/2019
Re “也许我错过了,但有没有人尝试过一个简单的泛型扩展方法?”:SixOThree 说“改用扩展方法Bronek 说“你可以通过对你定义的枚举类型实现扩展方法来做到这一点”。
6赞 Erik Karlsson 6/27/2015 #19

我最喜欢的 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

免責聲明:

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

5赞 Vivek 8/3/2015 #20

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

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

int answer = (int)Sample.Book;

现在答案将是 1。

0赞 VPP 4/12/2016 #21

在 Visual Basic 中,它应该是:

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

Private value As Integer = CInt(Question.Role)
4赞 Kamran Shahid 12/16/2016 #22

以下是扩展方法

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;
}
6赞 Jeffrey Ferreiras 12/6/2017 #23

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

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;
12赞 Gauravsa 7/27/2018 #24
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);
}

评论

0赞 Peter Mortensen 12/9/2019
示例代码的解释是有序的(通过编辑您的答案,而不是在注释中)。
0赞 Chad Grant 12/28/2019
零通常保留给枚举中的未设置/未知状态,这样定义它很不常见
-1赞 Jeff 3/3/2019 #25

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

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赞 Chad Grant 12/28/2019
请不要,您可以在一行 Convert.Changetype(e, e.GetTypeCode()) 中完成所有这些操作并取回一个对象,无需动态或扩展方法
0赞 Jeff 2/23/2020
我不同意使用转换。只需使用石膏会更容易。我的目的是能够在不使用强制转换的情况下将任何枚举转换为其值。这允许更改枚举类型,而不必更改所有关联的强制转换 - 但是什么时候会发生这种情况?扩展方法工作正常。但是,我遇到了一个问题,因为它是动态的,编译器无法进行类型检查(显然对于整个语句),这意味着在运行时会进行类型检查 - 这不是一个好的解决方案。我想我会回到演员阵容上。
5赞 Chad Grant 2/23/2020
我没有说使用它而不是强制转换,只是说这段代码是荒谬的,什么也做不了,实际上使问题变得更糟。我建议删除此解决方案
16赞 GinCanhViet 8/12/2019 #26

用:

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

这将导致 .value == 2

仅当枚举适合 .int

评论

2赞 RB. 8/14/2019
当然,只有当枚举适合 当然,因为返回一个整数时,这才成立。intGetHashCode
6赞 Abrar Jahin 9/23/2020 #27

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

如果你是这样的——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

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

0赞 IggyBar 1/12/2021 #28

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

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

0赞 Tayron Ovares 6/11/2021 #29
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 )
0赞 David L 3/15/2023 #30

几乎所有当前答案都使用或强制转换为目标类型之前的对象,这会导致装箱和取消装箱操作。这会导致堆分配,并且对于热路径可能不可接受。Convert

由于这些答案中的大多数都是编写的,因此引入了 System.Runtime.CompilerServices.Unsafe,从而实现了指针的低级操作。

结合泛型,该类允许我们安全地更改参数的基础类型,零分配,并且性能与空方法持续时间几乎无法区分:UnsafeSystem.Enum

public long GetEnumValue<T>(T enumInstance) where T : unmanaged, Enum
{
    var size = Unsafe.SizeOf<T>();
    
    if (size == Unsafe.SizeOf<byte>())
    {
        return Unsafe.As<T, byte>(ref enumInstance);
    }
    else if (size == Unsafe.SizeOf<short>())
    {
        return Unsafe.As<T, short>(ref enumInstance);
    }
    else if (size == Unsafe.SizeOf<int>())
    {
        return Unsafe.As<T, int>(ref enumInstance); 
    }
    else if (size == Unsafe.SizeOf<long>())
    {
        return Unsafe.As<T, long>(ref enumInstance);
    }
    
    return -1; // or throw if you prefer
}

Convert vs Unsafe benchmark


如果最好总是返回一个 int,你可以这样做,尽管如果枚举的支持字段超过 ,它将溢出:int.MaxValue

public int GetEnumValue<T>(T enumInstance) where T : unmanaged, Enum
{
    var size = Unsafe.SizeOf<T>();
    
    if (size == Unsafe.SizeOf<byte>())
    {
        return Unsafe.As<T, byte>(ref enumInstance);
    }
    else if (size == Unsafe.SizeOf<short>())
    {
        return Unsafe.As<T, short>(ref enumInstance);
    }
    else if (size == Unsafe.SizeOf<int>())
    {
        return Unsafe.As<T, int>(ref enumInstance); 
    }
    else if (size == Unsafe.SizeOf<long>())
    {
        return Unsafe.As<T, int>(ref enumInstance);
    }
    
    return -1; // or throw if you prefer
}

如果使用以下方法:

public enum EnumLong : long
{
    First,
    Second,
    Third = (long)(int.MaxValue) + 1
}

var val = GetEnumValue(EnumLong.Third);

-2147483648将由于溢出而返回。开发人员极不可能创建具有如此大标志值的枚举,但始终有可能。

-1赞 SoulSystem 6/29/2023 #31
public int QuestionToInt(Question q)
{
    return (int)q;
}

评论

0赞 General Grievance 7/3/2023
当您可以直接转换它时,为此定义一个全新的函数会更好吗?