公司里遗留下了相当多的 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()的更多相关文章

  1. Enum.GetHashCode()的问题

    先说一下,正常如果代码可以定义成枚举,我是比较倾向于定义成枚举的,类似这样: public enum Gender { /// <summary> /// 男 /// </summa ...

  2. unity踩坑2020-01-21

    这几天一直在测试一个类似于传奇的2d界面游戏,目前做的测试为: 人物动作响应,主要是8方向的判断和资源文件精灵的刷新. 学到的知识点: 1,Enum.GetHashCode() 可以得到这个枚举的索引 ...

  3. enum操作--获取枚举里的最大值

    一个应用系统,如果程序里没有任何enum的使用,我认为它的可读性是有待商榷的. 求枚举里的最大/最小枚举值, 其实是对Array进行操作: enum EnumTest { ddd = , eee } ...

  4. C# EnumHelper Enum的值,Description,ToString()的相互转换

    首先定义枚举类型,如下: /// <summary> /// 板块 /// </summary> public enum Plate {         [Descriptio ...

  5. MVC图片上传详解 IIS (安装SSL证书后) 实现 HTTP 自动跳转到 HTTPS C#中Enum用法小结 表达式目录树 “村长”教你测试用例 引用provinces.js的三级联动

    MVC图片上传详解   MVC图片上传--控制器方法 新建一个控制器命名为File,定义一个Img方法 [HttpPost]public ActionResult Img(HttpPostedFile ...

  6. C#中正确使用enum做Key的姿势

    C#中自定义enum,然后将其作为Dictionary的Key,通常的做法如下: using System; using System.Text; using System.Collections.G ...

  7. Enum枚举类使用集合

    1.使用扩展方法使用枚举值对于的Description属性值 public static class EnumExtenstion { public static string GetDescript ...

  8. C# 中 枚举Enum 一些转换的方法整理

    工作中 经常遇到枚举 的一些转换  特别是获取枚举备注等  特地整理下 方法以后使用 public void TestMethod1() { TestEnumOne colorEnum = TestE ...

  9. Swift enum(枚举)使用范例

    //: Playground - noun: a place where people can play import UIKit var str = "Hello, playground& ...

随机推荐

  1. VMware 不可恢复错误(svga)”解决方法

    虚拟机VMware 文件在迁移到另一台计算机时出现"VMware Workstation 不可恢复错误(svga)"  将另一台机器的 VMware 文件拷贝至本机,打开虚拟机出现 ...

  2. C#中的默认访问修饰符

    1.命名空间下的元素的默认访问修饰符 public : 同一程序集的其他任何代码或引用该程序集的其他程序集都可以访问该类型或成员.internal : 同一程序集中的任何代码都可以访问该类型或成员,但 ...

  3. [转]的C#实现三维数字地形漫游(基于Irrlicht)

    马省轩  任丽娜 摘  要:本文采用C#编程语言,利用Irrlicht三维图形引擎实现了三维数字地形的漫游.为三维数字地形显示提供了较易实现的解决方案. 关键词:C#   高度图 Irrlicht引擎 ...

  4. Qt——QLineEdit使用总结

    QLineEdit是一个单行文本编辑控件. 使用者可以通过很多函数,输入和编辑单行文本,比如撤销.恢复.剪切.粘贴以及拖放等. 通过改变QLineEdit的 echoMode() ,可以设置其属性,比 ...

  5. jquery-lazyload延迟加载图片 及 加载顺序 bug 修复

    jquery-lazyload延迟加载图片   代码修改片段 function update() { var counter = 0; /**fix by weiyj start***/ elemen ...

  6. 信息安全系统设计基础第一次实验报告 20135201&&20135306&&20135307

    信息安全系统设计基础实验 班级: 201353 姓名:张忻 张嘉琪 黄韧 学号:20135301 20135307 20135306 实验日期:2015.11.10 实验名称: S3C2410的lin ...

  7. 信息安全系统设计基础exp_1

    详见搭档20135322郑伟博客链接:http://www.cnblogs.com/zhengwei0712/

  8. C# GC 垃圾回收机制

    今天来谈谈C# 的GC ,也就是垃圾回收机制,非常的受教,总结如下 首先:谈谈托管,什么叫托管,我的理解就是托付C# 运行环境帮我们去管理,在这个运行环境中可以帮助我们开辟内存和释放内存,开辟内存一般 ...

  9. php模式设计之 适配器模式

    在这个有没有对象都要高呼“面向对象”的年代,掌握面向对象会给我们带来意想不到的方便.学编程的小伙伴从开始能写几行代码实现简单功能到后来懂得将一些重复的操作组合起来形成一个“函数”,再到后来将“函数”和 ...

  10. HTML5 中canvas支持触摸屏的签名面板

    1.前言 最近实在是太忙了,从国庆之后的辞职,在慢慢的找工作,到今天在现在的这家公司上班大半个月了,太多的心酸泪无以言表,面试过程中,见到的坑货公司是一家又一家,好几家公司自己都只是上一天班就走了,其 ...