如何在 C# 中将 int 转换为 enum?
如何在 C# 中将 int
转换为 enum
?
How do I cast an int
to an enum
in C#?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
如何在 C# 中将 int
转换为 enum
?
How do I cast an int
to an enum
in C#?
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(30)
就我而言,我需要从 WCF 服务返回枚举。 我还需要一个友好的名称,而不仅仅是 enum.ToString()。
这是我的 WCF 课程。
这是从枚举获取描述的扩展方法。
执行:
In my case, I needed to return the enum from a WCF service. I also needed a friendly name, not just the enum.ToString().
Here's my WCF Class.
Here's the Extension method that gets the Description from the Enum.
Implementation:
它可以帮助您将任何输入数据转换为用户所需的枚举。 假设您有一个如下所示的枚举,默认情况下为 int。 请在枚举的开头添加一个默认值。 当未找到与输入值匹配的情况时,在辅助方法中使用该方法。
NB:这里我尝试将值解析为int,因为枚举默认是int
如果您像这样定义枚举,它是 byte 类型。
您需要将辅助方法的解析从
byte.TryParse(value.ToString(), out tempType)
我检查我的方法以获取以下输入,
抱歉我的英语
It can help you to convert any input data to user desired enum. Suppose you have an enum like below which by default int. Please add a Default value at first of your enum. Which is used at helpers medthod when there is no match found with input value.
N.B: Here I try to parse value into int, because enum is by default int
If you define enum like this which is byte type.
You need to change parsing at helper method from
to
byte.TryParse(value.ToString(), out tempType)
I check my method for following inputs
sorry for my english
您可以使用扩展方法。
像下面的代码一样使用它:
枚举:
用法:
You can use an extension method.
Use it like the below code:
Enum:
Usage:
我更喜欢使用可为空的枚举类型变量的简短方法。
I prefer a short way using a nullable enum type variable.
您只需使用显式转换将 int 转换为 enum 或 enum 转换为 int
You simply use Explicit conversion Cast int to enum or enum to int
我不知道从哪里得到这个枚举扩展的部分,但它来自 stackoverflow。 对此我感到很抱歉! 但我采用了这个并将其修改为带有标志的枚举。
对于带有标志的枚举,我这样做了:
示例:
I don't know anymore where I get the part of this enum extension, but it is from stackoverflow. I am sorry for this! But I took this one and modified it for enums with Flags.
For enums with Flags I did this:
Example:
您只需执行以下操作:
要确保只转换正确的值,否则可以抛出异常:
请注意,使用 IsDefined 的成本很高,甚至不仅仅是转换,因此取决于您的实现来决定使用它还是不是。
You just do like below:
To make sure that you only cast the right values and that you can throw an exception otherwise:
Note that using IsDefined is costly and even more than just casting, so it depends on your implementation to decide to use it or not.
转换与
Enum
的不同方式Different ways to cast to and from
Enum
在 C# 中将 int 转换为 enum 的简单明了的方法:
The easy and clear way for casting an int to enum in C#:
下面是将
Int32
转换为Enum
的扩展方法。即使该值高于可能的最大值,它也会遵循按位标志。 例如,如果您有一个可能为 1、2 和 4 的枚举,但 int 为 9,如果没有 8,它会将其理解为 1。 这使您可以在代码更新之前更新数据。
Here's an extension method that casts
Int32
toEnum
.It honors bitwise flags even when the value is higher than the maximum possible. For example if you have an enum with possibilities 1, 2, and 4, but the int is 9, it understands that as 1 in absence of an 8. This lets you make data updates ahead of code updates.
对于字符串,您可以执行以下操作:
并确保检查结果以确定转换是否失败。
对于 int,您可以执行以下操作:
For string, you can do the following:
And make sure to check the result to determine if the conversion failed.
For int, you can do the following:
下面是一个很好的枚举实用程序类
Below is a nice utility class for Enums
我正在使用这段代码将
int
转换为我的enum
:我发现它是最好的解决方案。
I am using this piece of code to cast
int
to myenum
:I find it the best solution.
举个例子:
Take the following example:
我认为要获得完整的答案,人们必须了解枚举在 .NET 内部是如何工作的。
工作原理
.NET 中的枚举是一种将一组值(字段)映射到基本类型(默认为
int
)的结构。 但是,您实际上可以选择枚举映射到的整数类型:在这种情况下,枚举被映射到
short
数据类型,这意味着它将作为 Short 存储在内存中,并且行为如下当您施放并使用它时会出现短路。如果从 IL 的角度来看,(normal, int) 枚举看起来像这样:
这里应该引起您注意的是
value__
与枚举值分开存储。 在上面的枚举Foo
中,value__
的类型是 int16。 这基本上意味着您可以在枚举中存储您想要的任何内容,只要类型匹配。此时我想指出
System.Enum
是一个值类型,这基本上意味着BarFlag
将占用内存中的 4 个字节,而Foo
将占用 2 —— 例如底层类型的大小(实际上比这更复杂,但是嘿......)。答案
因此,如果您有一个整数想要映射到枚举,则运行时只需执行两件事:复制 4 个字节并将其命名为其他名称(枚举的名称) 。 复制是隐式的,因为数据存储为值类型 - 这基本上意味着,如果您使用非托管代码,您可以简单地交换枚举和整数,而无需复制数据。
为了安全起见,我认为最好的做法是知道基础类型是相同的或隐式可转换的并确保枚举值存在(默认情况下不检查它们!)。
要了解其工作原理,请尝试以下代码:
请注意,转换为
e2
也可以! 从上面的编译器角度来看,这是有道理的:当Console.WriteLine
调用ToString()
时,value__
字段简单地填充为 5 或 6。 ,e1
的名称已解析,而e2
的名称未解析。如果这不是您想要的,请使用
Enum.IsDefined(typeof(MyEnum), 6)
检查您要转换的值是否映射到已定义的枚举。另请注意,我明确说明了枚举的基础类型,即使编译器实际上会检查这一点。 我这样做是为了确保我不会在未来遇到任何意外。 要查看这些惊喜的实际效果,您可以使用以下代码(实际上我在数据库代码中经常看到这种情况发生):
I think to get a complete answer, people have to know how enums work internally in .NET.
How stuff works
An enum in .NET is a structure that maps a set of values (fields) to a basic type (the default is
int
). However, you can actually choose the integral type that your enum maps to:In this case the enum is mapped to the
short
data type, which means it will be stored in memory as a short and will behave as a short when you cast and use it.If you look at it from a IL point of view, a (normal, int) enum looks like this:
What should get your attention here is that the
value__
is stored separately from the enum values. In the case of the enumFoo
above, the type ofvalue__
is int16. This basically means that you can store whatever you want in an enum, as long as the types match.At this point I'd like to point out that
System.Enum
is a value type, which basically means thatBarFlag
will take up 4 bytes in memory andFoo
will take up 2 -- e.g. the size of the underlying type (it's actually more complicated than that, but hey...).The answer
So, if you have an integer that you want to map to an enum, the runtime only has to do 2 things: copy the 4 bytes and name it something else (the name of the enum). Copying is implicit because the data is stored as value type - this basically means that if you use unmanaged code, you can simply interchange enums and integers without copying data.
To make it safe, I think it's a best practice to know that the underlying types are the same or implicitly convertible and to ensure the enum values exist (they aren't checked by default!).
To see how this works, try the following code:
Note that casting to
e2
also works! From the compiler perspective above this makes sense: thevalue__
field is simply filled with either 5 or 6 and whenConsole.WriteLine
callsToString()
, the name ofe1
is resolved while the name ofe2
is not.If that's not what you intended, use
Enum.IsDefined(typeof(MyEnum), 6)
to check if the value you are casting maps to a defined enum.Also note that I'm explicit about the underlying type of the enum, even though the compiler actually checks this. I'm doing this to ensure I don't run into any surprises down the road. To see these surprises in action, you can use the following code (actually I've seen this happen a lot in database code):
或者,使用扩展方法而不是单行:
用法:
或
Alternatively, use an extension method instead of a one-liner:
Usage:
OR
只需转换它:
使用
Enum 检查它是否在范围内。已定义
:Just cast it:
Check if it's in range using
Enum.IsDefined
:下面是一个稍微好一点的扩展方法:
The following is a slightly better extension method:
这会使用 Tawani 的实用程序类。 我用它来转换可能不完整的命令行开关变量。 由于枚举不能为空,因此您在逻辑上应该提供一个默认值。 可以这样调用:
这是代码:
仅供参考:问题是关于整数,没有人提到整数也会在 Enum.TryParse() 中显式转换
This parses integers or strings to a target enum with partial matching in .NET 4.0 using generics like in Tawani's utility class. I am using it to convert command-line switch variables which may be incomplete. Since an enum cannot be null, you should logically provide a default value. It can be called like this:
Here's the code:
FYI: The question was about integers, which nobody mentioned will also explicitly convert in Enum.TryParse()
稍微偏离了原来的问题,但我找到了堆栈溢出问题的答案从枚举中获取 int 值有用。 使用
public const int
属性创建一个静态类,使您可以轻松地将一堆相关的int
常量收集在一起,然后不必将它们强制转换为int< /code> 使用它们时。
显然,一些枚举类型的功能将会丢失,但对于存储一堆数据库 id 常量来说,这似乎是一个非常整洁的解决方案。
Slightly getting away from the original question, but I found an answer to Stack Overflow question Get int value from enum useful. Create a static class with
public const int
properties, allowing you to easily collect together a bunch of relatedint
constants, and then not have to cast them toint
when using them.Obviously, some of the enum type functionality will be lost, but for storing a bunch of database id constants, it seems like a pretty tidy solution.
从 int:
从字符串:
动态(编译时类型未知):
From an int:
From a string:
Dynamically (type not known at compile-time):
来自字符串:(
Enum.Parse
已过时,请使用Enum.TryParse
)From a string: (
Enum.Parse
is out of Date, useEnum.TryParse
)您应该构建某种类型匹配松弛以使其更加健壮。
测试用例
You should build in some type matching relaxation to be more robust.
Test Case
要将字符串转换为 ENUM 或将 int 转换为 ENUM 常量,我们需要使用 Enum.Parse 函数。 这是一个 YouTube 视频https://www.youtube.com/watch?v=4nhx4VwdRDk 它实际上演示了字符串,这同样适用于 int。
代码如下所示,其中“red”是字符串,“MyColors”是具有颜色常量的颜色 ENUM。
To convert a string to ENUM or int to ENUM constant we need to use Enum.Parse function. Here is a youtube video https://www.youtube.com/watch?v=4nhx4VwdRDk which actually demonstrate's with string and the same applies for int.
The code goes as shown below where "red" is the string and "MyColors" is the color ENUM which has the color constants.
这是一个标志枚举感知的安全转换方法:
This is an flags enumeration aware safe convert method:
如果您有一个充当位掩码并且可以表示 [Flags] 枚举中的一个或多个值的整数,则可以使用此代码将各个标志值解析到一个列表中:
请注意,这假设 < 的基础类型code>enum 是一个有符号的 32 位整数。 如果它是不同的数字类型,则必须更改硬编码的 32 以反映该类型中的位(或使用
Enum.GetUnderlyingType()
以编程方式派生它)If you have an integer that acts as a bitmask and could represent one or more values in a [Flags] enumeration, you can use this code to parse the individual flag values into a list:
Note that this assumes that the underlying type of the
enum
is a signed 32-bit integer. If it were a different numerical type, you'd have to change the hardcoded 32 to reflect the bits in that type (or programatically derive it usingEnum.GetUnderlyingType()
)有时您有一个
MyEnum
类型的对象。 就像那时:
Sometimes you have an object to the
MyEnum
type. LikeThen:
如果您已准备好使用 4.0 .NET 框架,这里有一个新的 Enum.TryParse() 函数非常有用,并且与 [Flags] 属性配合得很好。 请参阅Enum.TryParse 方法(字符串,TEnum%)
If you're ready for the 4.0 .NET Framework, there's a new Enum.TryParse() function that's very useful and plays well with the [Flags] attribute. See Enum.TryParse Method (String, TEnum%)
对于数值,这更安全,因为无论如何它都会返回一个对象:
For numeric values, this is safer as it will return an object no matter what: