博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
c# —— 枚举和值的隐藏副作用
阅读量:3524 次
发布时间:2019-05-20

本文共 2015 字,大约阅读时间需要 6 分钟。

最近,我遇到了enum的问题,我想分享一下,以防其他人遇到它。

enum是什么?

Enums是一个数值常量列表,可以帮助我们处理许多情况,例如某些东西可以有标记或属性,以区别于另一个对象,或者它们代表方法的不同选项。其他时候,它们代表一个对象或关系的状态,例如,我们可以使用Employee enum告诉我们一个人是经理,副总裁,CEO

但无论我们给enum什么名称,在后台,它只是一个用于代表该状态的数字,如下所示:

enum Foo {Bar1,Bar2,Bar3,}

因此,在本例中,我们声明了一个名为Fooenum,它可以具有3个值之一,Bar1,隐式地具有0Bar2,其值为1Bar3具有值2

问题在于enum的背景值以及我们如何使用它,例如,因为我们知道Bar2的值为1,我们可以将数字1转换为Foo类型的枚举,我们将得到如下的Bar2

Console.WriteLine((Foo)1);

//会输出: Bar2

但是既然我们在谈论数字,那么enums也可以映射到这样的特定值:

enum Foo {Bar1 = 2,Bar2,Bar3 = 5,}

基本上,在这种情况下,Bar1将有一个值2, Bar2将具有值3Bar3并将具有值5

而现在是奇怪的部分和副作用。

我们可以用enum为同一个值定义两个或多个标识符,如下所示:

enum Foo {Bar1 = 2,Bar2 = 2,Bar3,}

请注意,Bar1Bar2具有相同的值(不一定是2)。因此,如果我们现在运行以下命令,则运行时不知道我们引用的是哪个标识符,因此它将为中间标识符提供该值:

Console.WriteLine((Foo)2);

//会输出:Bar2因为它是最新的

中间的意思是,即使我们有这样定义的enum,输出也是相同的:

enum Foo {Bar1 = 2,Bar2 = 2,Bar3 = 2,}

所以无论我们如何运行它,输出仍然是Bar2 ,但如果我们有这样的enum定义:

enum Foo {Bar1 = 2,Bar2 = 2,Bar3 = 2,Bar4 = 2,Bar5 = 2,Bar6 = 2,Bar7 = 2}

运行相同的命令将给我们,Bar4因为它是中间的,如果我们的enum数是偶数的,那么它将使我们中间的枚举数接近尾数,所以对于两个enum标识符,它将给我们第二个,三个它会给我们第二个,但是对于四个它将给我们第三个,同样,如果我们有五个相同值的标识符。对于六,它将给我们第三个,依此类推。

但是,当在Bar1之前像这样放置另一个值更低的enum标识符时,会发生什么情况呢?

enum Foo {Bar,Bar1 = 2,Bar2 = 2,Bar3,}

现在,如果我们运行输出命令,它将不会显示enum具有该值的中间值,而是显示中间值1所以在这种情况下,它将显示Bar1和前一个enum,但是让我们更进一步来看看这个枚举:

enum Foo {Bar,Bar1 = 2,Bar2 = 2,Bar3 = 2,Bar4 = 2,Bar5 = 2,Bar6 = 2,Bar7 = 2}

那么值的输出2将是Bar3,甚至更糟糕的是,如果我们要在Bar1之前再添加2个值(我把值移到5,这样我们就不会与要检查的值重叠):

enum Foo {Bar0,Bar00,Bar000,Bar1 = 5,Bar2 = 5,Bar3 = 5,Bar4 = 5,Bar5 = 5,Bar6 = 5,Bar7 = 5}

然后,如果我们运行命令:

Console.WriteLine((Foo)5);

//会输出: Bar2

因此,对于在该序列之前添加的每两个标识符,它将返回一个,但是我尝试了别的方法,在序列之后又添加了两个标识符,猜猜看,它回到了Bar3,然后又添加了两个,它转到了Bar4,如果您继续添加这么多标识符,那么它应该比Bar7多,那么它将循环并显示Bar1

我承认,这让我感到困惑,因为这意味着当给定值有多个标识符时,按值使用enum变得不可预测,特别是当不清楚时,并且在开发过程中,我们添加该enum而不知道它会影响我们,并且我们可能会依赖于这些标识符的输出。

尽管我们不会看到每个值都有两个以上标识符的情况,但仍然需要注意,因为按值使用enum并不少见,而且我的意思是,当我想到这一点时,至少有三种常见的用法,就像HTML下拉列表中有数字值一样,调用使用数字来表示某个enumWebAPI调用,数据库持久性,就像MongoDB将使用数值来存储一个enum,并且我确信还有更多的情况使用这种机制。

幸运的是,我的一位同事想出了一个答案来避免这个问题,那就是保存或发送enum值作为文本然后解析它们,这样,我们肯定知道我们指的是正确的标识符。

PS:其实最好是设法让其值唯一即可

原文地址:

转载地址:http://rwzhj.baihongyu.com/

你可能感兴趣的文章
synchronized的局限性与lock的好处
查看>>
redis和memcached有什么区别?
查看>>
Spring中的设计模式
查看>>
如何设计一个秒杀系统 -- 架构原则
查看>>
如何设计一个秒杀系统 -- 动静分离方案
查看>>
JWT 快速了解
查看>>
实习日志一
查看>>
排序算法稳定性
查看>>
图算法总结(判断有环、最短路径)
查看>>
spring中的类
查看>>
python练习编程网址
查看>>
Python练习小程序1
查看>>
pytorch用于多标签分类的bceloss
查看>>
C++程序设计:打印杨辉三角形
查看>>
C# 方法内改变参数的引用 不影响方法外的值
查看>>
C# vs2019 智能提示中文突然变成英文
查看>>
linux开机引导和启动过程(详细)(含配置文件解读)
查看>>
Vue学习笔记——常见简写&修饰符
查看>>
vue-element-admin源码解读——项目启动过程
查看>>
zcmu 1577 食堂的蛋饼(思维)
查看>>