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

那enum是什么?

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

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

enum Foo {
Bar1,
Bar2,
Bar3,
}

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

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

Console.WriteLine((Foo)1);

//会输出: Bar2

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

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

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

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

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

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

请注意,Bar1和Bar2具有相同的值(不一定是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下拉列表中有数字值一样,调用使用数字来表示某个enum值WebAPI调用,数据库持久性,就像MongoDB将使用数值来存储一个enum,并且我确信还有更多的情况使用这种机制。

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

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

原文地址:https://www.codeproject.com/Articles/1266988/The-Hidden-Side-effect-of-Enums-and-Values

c# —— 枚举和值的隐藏副作用相关推荐

  1. 把数据库中有关枚举项值的数字字符串转换成文字字符串

    原文:把数据库中有关枚举项值的数字字符串转换成文字字符串 标题可能无法表达我的本意.比如,有这样一个枚举: public enum MyChoice { MyFirstChoice = 0, MySe ...

  2. 使用MyBatis简化枚举类值的存储和读取

    场景描述 我们在实际场景中经常会遇到需要将枚举值存储到数据库中,或是将从数据库中查询到的值对应到枚举类上的情况. 比如表process大致定义如下: -- ---------------------- ...

  3. swift_031(Swift 中的枚举/原始值(RawValues))

    枚举定义语法 首先,我们来看看在 swift 中定义枚举的语法: enum WeekDay {case Mondaycase Tuesdaycase Wednesdaycase Thursdaycas ...

  4. C#枚举、值、字符串的相互转换

    目录 枚举的定义 使用方式 优点 代码示例 枚举的定义 枚举是整数类型,用户自定义的整数类型的一个集合. 使用方式 public enum A {a=0,b=1,c=2 } 注意:枚举定义的不同变量之 ...

  5. aspose.cells 无法读取公式值_隐藏 Excel表格、公式的9种方法

    Excel,站在你面前,你却看不见..... 1.给Excel文件穿上隐身衣 在win10系统中,隐藏文件变得如此容易,选取文件点"隐藏所选项目",再去掉"隐藏的项目&q ...

  6. java枚举 取值_秒懂系列,超详细Java枚举教程!!!

    深入理解Java枚举 一.什么是枚举 1.1 什么是枚举? 至于枚举,我们先拿生活中的枚举来入手,然后再引申Java中的枚举,其实它们的意义很相似. 谈到生活中的枚举,假如我们在玩掷骰子的游戏,在我们 ...

  7. css --- 使用媒体查询当屏幕宽度小于某个值时,隐藏掉某个类

    Bootstrap提供了一个封装好的类: .hidden-xs: 当屏幕宽度<768px时隐藏 .hidden-sm: 当屏幕768px <= 宽度<992px时隐藏 .hidden ...

  8. chrome 不记录填写值_Chrome隐藏技巧,效率党收下

    主持人: 大家好 今天我们的节目,有请到一位不愿透明网名的挨踢君 我们知道挨踢君一直是Chrome的忠实拥趸 那么Chrome到底好在哪里 相比其他浏览器,它又有什么优势呢? 我们来采访一下挨踢君 主 ...

  9. java获取枚举的值_JAVA枚举Enum,通过枚举值获取枚举类型

    枚举类: import java.util.Optional; public enum PurchaseDemandEnum { YJJSL(1,"研究技术类"), XTGCL(2 ...

最新文章

  1. 10款著名的代码(文本)编辑器
  2. js中如何判断一个DOM对象是否存在?
  3. python中[-1]、[-1]、[-1]、[n-1]使用方法
  4. Android逆向文档阅读笔记-Android Application Fundamentals
  5. 基于jetty9 编程构建嵌入式https 服务器
  6. 2017.2.14-15自测(那些普及神题)
  7. 批处理只执行第一句,其他的不被执行,怎么办?
  8. 【对讲机的那点事】公网对讲机的物联卡你了解吗?
  9. 丝杠螺母传动机构设计
  10. html表单有几部分组成,网页制作时表单由哪两部分组成
  11. JAVA java学习(46)——————如何将Eclipse设置为中文版
  12. 北理工集训 Day1—Day2 (部分算法题目)
  13. python手机端如何下载_过去,哔哩哔哩上面的视频只能在手机上面下载;现在,我用Python爬虫实现了能在PC端上面下载...
  14. Java_String_Arrays_Character_BigDecimal_Calendar_Math_System
  15. 修改主分区表给U盘分区
  16. 《幸福人生 从心开始》讲座参后感
  17. Android集成友盟推送最详细介绍
  18. 谷歌浏览器无法打开localhost:3000,打开localhost就跳转测试地址问题
  19. 计算机网络专业调研报告前言,计算机网络专业调研报告材料.docx
  20. 基于 AT89C51 单片机的数字时钟设计

热门文章

  1. 服务器java项目转移到另一个盘_将svn的项目从一台服务器转移到另外一台服务器...
  2. java中为什么还要防止内存泄露_JAVA防止内存的泄漏什么意思,内存还能泄露?...
  3. 算法与程序设计_算法与程序设计入门-简单计算题1
  4. java 线程池 复用机制,java的线程池框架及线程池的原理
  5. 平面海报设计素材|几何风格极简流行风,继续
  6. 设计干货之插画模板|彩色手绘自然风景城市风景
  7. 数据结构猴子选大王java_数据结构例子-猴子选大王
  8. python用一行代码编写一个回声程序_Python源码分析2 - 一个简单的Python程序的执行...
  9. Intel初始化和模式切换示例
  10. 三星开源的 tcpflow 抓包工具