zoukankan      html  css  js  c++  java
  • 慎用 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
                )

                // 文档:EnumBoxTestProgram.cs, 行 14,列 9
                // 0x025C: 00
                IL_0000: nop
                // 文档:EnumBoxTestProgram.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
                // 文档: EnumBoxTestEnumBoxTestProgram.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
                // 文档:EnumBoxTestEnumBoxTestProgram.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
                )

                // 文档: EnumBoxTestEnumBoxTestProgram.cs, 行 14,列 9
                // 0x025C: 00
                IL_0000: nop
                // 文档:EnumBoxTestEnumBoxTestProgram.cs, 行 15,列 13
                // 0x025D: 17
                IL_0001: ldc.i4.1
                // 0x025E: 0A
                IL_0002: stloc.0
                // 文档: EnumBoxTestEnumBoxTestProgram.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
                // 文档: EnumBoxTestEnumBoxTestProgram.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();

    }

    }

  • 相关阅读:
    GIS有关GP服务的发布和调用
    博文列表
    VCL编写笔记整理
    Delphi操作Excel(Use Oel)
    使用 ImageEnView 给图片加水印,及建缩略图
    Delphi下MSMQ(Mircosoft Message Queue)实例(私有队列)
    从给定字符串中截取n个字节的字符(解决汉字截取乱码问题)
    tbytes 转 十六进制 string
    Delphi中拖动的方式来移动TPageControl的Tab
    delphi TEdit透明
  • 原文地址:https://www.cnblogs.com/zhshlimi/p/5257199.html
Copyright © 2011-2022 走看看