慎用 Enum.GetHashCode()
公司里遗留下了相当多的 Enum.GetHashCode()来获取枚举值的代码
但是这会产生装箱行为的!!因为Enum是值类型,GetHashCode()是Object的方法,调用GetHashCode必定要装箱成Object类型才能调用
同理:Enum.ToString()也会装箱 用 Enum.GetName( typeof (Color), color);//推荐
namespace EnumBoxTest
{
class Program
{
enum Color
{
None=0,
Red=1,
Black=2
}
static void Main(string[] args)
{
int colorId = Color.Red.GetHashCode();
Console.WriteLine(colorId);
}
}
}
有IL代码有真相
在下面 IL_0002: box EnumBoxTest.Program/Color 代码中,可以清晰看到装箱行为
namespace EnumBoxTest
{
.class private auto ansi beforefieldinit EnumBoxTest.Program
extends [mscorlib]System.Object
{
// 嵌套类型
.class nested private auto ansi sealed Color
extends [mscorlib]System.Enum
{
// 成员
.field public specialname rtspecialname int32 value__
.field public static literal valuetype EnumBoxTest.Program/Color None = int32(0)
.field public static literal valuetype EnumBoxTest.Program/Color Red = int32(1)
.field public static literal valuetype EnumBoxTest.Program/Color Black = int32(2)
} // 类 Color 结束
// 方法
.method private hidebysig static
void Main (
string[] args
) cil managed
{
// 方法起始 RVA 地址 0x2050
// 方法起始地址(相对于文件绝对值:0x0250)
// 代码长度 21 (0x15)
.maxstack 1
.entrypoint
.locals init (
[0] int32 colorId
)
// 文档:\EnumBoxTest\Program.cs, 行 14,列 9
// 0x025C: 00
IL_0000: nop
// 文档:\EnumBoxTest\Program.cs, 行 15,列 13
// 0x025D: 17
IL_0001: ldc.i4.1
// 0x025E: 8C 03 00 00 02
IL_0002: box EnumBoxTest.Program/Color
// 0x0263: 6F 11 00 00 0A
IL_0007: callvirt instance int32 [mscorlib]System.Object::GetHashCode()
// 0x0268: 0A
IL_000c: stloc.0
// 文档: \EnumBoxTest\EnumBoxTest\Program.cs, 行 16,列 13
// 0x0269: 06
IL_000d: ldloc.0
// 0x026A: 28 12 00 00 0A
IL_000e: call void [mscorlib]System.Console::WriteLine(int32)
// 0x026F: 00
IL_0013: nop
// 文档:\EnumBoxTest\EnumBoxTest\Program.cs, 行 18,列 9
// 0x0270: 2A
IL_0014: ret
} // 方法 Program::Main 结束
.method public hidebysig specialname rtspecialname
instance void .ctor () cil managed
{
// 方法起始 RVA 地址 0x2071
// 方法起始地址(相对于文件绝对值:0x0271)
// 代码长度 7 (0x7)
.maxstack 8
// 0x0272: 02
IL_0000: ldarg.0
// 0x0273: 28 13 00 00 0A
IL_0001: call instance void [mscorlib]System.Object::.ctor()
// 0x0278: 2A
IL_0006: ret
} // 方法 Program::.ctor 结束
} // 类 EnumBoxTest.Program 结束
}
现在将代码换为
namespace EnumBoxTest
{
class Program
{
enum Color
{
None=0,
Red=1,
Black=2
}
static void Main(string[] args)
{
int colorId = (int)Color.Red;
Console.WriteLine(colorId);
}
}
}
IL代码为:
.namespace EnumBoxTest
{
.class private auto ansi beforefieldinit EnumBoxTest.Program
extends [mscorlib]System.Object
{
// 嵌套类型
.class nested private auto ansi sealed Color
extends [mscorlib]System.Enum
{
// 成员
.field public specialname rtspecialname int32 value__
.field public static literal valuetype EnumBoxTest.Program/Color None = int32(0)
.field public static literal valuetype EnumBoxTest.Program/Color Red = int32(1)
.field public static literal valuetype EnumBoxTest.Program/Color Black = int32(2)
} // 类 Color 结束
// 方法
.method private hidebysig static
void Main (
string[] args
) cil managed
{
// 方法起始 RVA 地址 0x2050
// 方法起始地址(相对于文件绝对值:0x0250)
// 代码长度 11 (0xb)
.maxstack 1
.entrypoint
.locals init (
[0] int32 colorId
)
// 文档: \EnumBoxTest\EnumBoxTest\Program.cs, 行 14,列 9
// 0x025C: 00
IL_0000: nop
// 文档:\EnumBoxTest\EnumBoxTest\Program.cs, 行 15,列 13
// 0x025D: 17
IL_0001: ldc.i4.1
// 0x025E: 0A
IL_0002: stloc.0
// 文档: \EnumBoxTest\EnumBoxTest\Program.cs, 行 16,列 13
// 0x025F: 06
IL_0003: ldloc.0
// 0x0260: 28 11 00 00 0A
IL_0004: call void [mscorlib]System.Console::WriteLine(int32)
// 0x0265: 00
IL_0009: nop
// 文档: \EnumBoxTest\EnumBoxTest\Program.cs, 行 18,列 9
// 0x0266: 2A
IL_000a: ret
} // 方法 Program::Main 结束
.method public hidebysig specialname rtspecialname
instance void .ctor () cil managed
{
// 方法起始 RVA 地址 0x2067
// 方法起始地址(相对于文件绝对值:0x0267)
// 代码长度 7 (0x7)
.maxstack 8
// 0x0268: 02
IL_0000: ldarg.0
// 0x0269: 28 12 00 00 0A
IL_0001: call instance void [mscorlib]System.Object::.ctor()
// 0x026E: 2A
IL_0006: ret
} // 方法 Program::.ctor 结束
} // 类 EnumBoxTest.Program 结束
}
性能测试如下:
enum MyEnum
{
Blank=0,
Write=1
}
class Program
{
static void Main(string[] args)
{
int v = 0;
Stopwatch sw=new Stopwatch();
sw.Reset();
sw.Start();
for (int i = 0; i < 1000*1000;i++)
{
v = MyEnum.Blank.GetHashCode();
}
sw.Stop();
Console.WriteLine("GetHashCode:{0}",sw.ElapsedMilliseconds);//耗时 81ms
sw.Reset();
sw.Start();
for (int i = 0; i < 1000 * 1000; i++)
{
v = (int)MyEnum.Blank ;
}
sw.Stop();
Console.WriteLine("(int):{0}", sw.ElapsedMilliseconds);//耗时 2ms
Console.Read();
}
}
慎用 Enum.GetHashCode()的更多相关文章
- Enum.GetHashCode()的问题
先说一下,正常如果代码可以定义成枚举,我是比较倾向于定义成枚举的,类似这样: public enum Gender { /// <summary> /// 男 /// </summa ...
- unity踩坑2020-01-21
这几天一直在测试一个类似于传奇的2d界面游戏,目前做的测试为: 人物动作响应,主要是8方向的判断和资源文件精灵的刷新. 学到的知识点: 1,Enum.GetHashCode() 可以得到这个枚举的索引 ...
- enum操作--获取枚举里的最大值
一个应用系统,如果程序里没有任何enum的使用,我认为它的可读性是有待商榷的. 求枚举里的最大/最小枚举值, 其实是对Array进行操作: enum EnumTest { ddd = , eee } ...
- C# EnumHelper Enum的值,Description,ToString()的相互转换
首先定义枚举类型,如下: /// <summary> /// 板块 /// </summary> public enum Plate { [Descriptio ...
- MVC图片上传详解 IIS (安装SSL证书后) 实现 HTTP 自动跳转到 HTTPS C#中Enum用法小结 表达式目录树 “村长”教你测试用例 引用provinces.js的三级联动
MVC图片上传详解 MVC图片上传--控制器方法 新建一个控制器命名为File,定义一个Img方法 [HttpPost]public ActionResult Img(HttpPostedFile ...
- C#中正确使用enum做Key的姿势
C#中自定义enum,然后将其作为Dictionary的Key,通常的做法如下: using System; using System.Text; using System.Collections.G ...
- Enum枚举类使用集合
1.使用扩展方法使用枚举值对于的Description属性值 public static class EnumExtenstion { public static string GetDescript ...
- C# 中 枚举Enum 一些转换的方法整理
工作中 经常遇到枚举 的一些转换 特别是获取枚举备注等 特地整理下 方法以后使用 public void TestMethod1() { TestEnumOne colorEnum = TestE ...
- Swift enum(枚举)使用范例
//: Playground - noun: a place where people can play import UIKit var str = "Hello, playground& ...
随机推荐
- 22Spring_JdbcTemplatem模板工具类的使用——使用外部属性文件来配置(properties)
前一篇文章写得是xml文件来配置数据库连接的.但是为了方便,我们实际中采用的是properties文件的方式来配置数据库的.修改properties 文件 会比 修改 xml文件 方便. 做法是: 将 ...
- MVC4 WebAPI POST数据问题
api [HttpPost] public string PostAvartos(Test model) { if (model != null) { LoggerHelper.WriteInfo(m ...
- usb驱动开发3之先看core
上节中看到usb目录中有一个core目录,凡是认识这个core单词的人都会想要先看看它是什么,对不?用LDD3中一幅图,来表述usb core所处地位. usb core负责实现一些核心的功能,为别的 ...
- 一些正则验证-JS
Validation = { textCount: function(field, counter, maxLimit) { var message = $(field).val(); if ($(f ...
- listview的头布局把我的ACTION_DOWN事件给吃了.....
因为头布局的viewpager自己处理点击事件 public boolean dispatchTouchEvent(MotionEvent ev) { switch (ev.getAction()) ...
- Android Home键状态保存运用场景
当我们在一个Activity中有接收Intent过来的值,或者当前Activity有保存数据时候,如果此时不小心按到了Home键,然后没有及时回来而是运行了其它应用程序,当你想起来的时候,恐怕已经是几 ...
- Opencv step by step - 自适应阈值
上个博客提到的阈值化只是针对图像全局进行阈值化,opencv提供了一个更好的函数cvAdaptiveThreshold,可以做到局部特征的阈值化,这样一来, 整个图像的信息可以被更好的提取. #inc ...
- 20145222黄亚奇《Java程序设计》第1周学习总结
教材学习内容总结 BJVM是Java程序唯一认识的操作系统,其可执行文件为.class文档 Java的三大平台为Java SE,Java EE,Java ME. Java SE的四个部分为:JVM,J ...
- CS:APP2e Y86处理器模拟器∗指南
CS:APP2e Y86处理器模拟器∗指南 Randal E.Bryant David R. O'Hallaron 2013年7月29日 本文档描述了处理器模拟器,伴随的表示在第4章Y86处理器架构的 ...
- Win10/UWP开发—使用Cortana语音指令启动前台App
这两天进群(53078485)找大咖的童鞋比较多,只是大咖比较忙,目前Demo还没有要到,这里先给大家转载一篇Aran大咖的博客学习下,以下是原文: Win10开发中最具有系统特色的功能点绝对少不了集 ...