如何在没有装箱的情况下检索枚举的哈希码?

Bil*_*eal 9 c# clr hash hashtable

如果有一个枚举存储在聚合类型中,则可能希望将其包含在类型的哈希代码中(假设典型的" 乘以素数 "哈希函数).如果只是调用SomeEnum.GetHashCode(),看起来即使在发布版本中,JIT也会对实例进行打包.

对此进行分析显示我的应用程序花费了大约10%的时间在各种GetHashCode函数中使用了拳击枚举.

几种值类型实现IEquatable或类似的接口,允许GetHashCode作为静态方法调用; 这避免了拳击.但是System.Enum不提供静态过载GetHashCode.有没有一些方法来计算应该使用的代码但是避免装箱?

jam*_*eff 5

您可以转换为枚举的基础类型(通常int除非枚举定义另有指定)并使用该类型的重写GetHashCode()方法.

enum TestEnum
{
    Test1,
    Test2
}

TestEnum t = TestEnum.Test1;
((int)t).GetHashCode(); // no boxing
t.GetHashCode(); // boxing
Run Code Online (Sandbox Code Playgroud)

以下是此代码的IL:

IL_0000:  nop
IL_0001:  ldc.i4.0
IL_0002:  stloc.0
IL_0003:  ldloc.0
IL_0004:  stloc.1
IL_0005:  ldloca.s   V_1
IL_0007:  call       instance int32 [mscorlib]System.Int32::GetHashCode()
IL_000c:  pop
IL_000d:  ldloc.0
IL_000e:  box        ConsoleApplication1.Program/TestEnum
IL_0013:  callvirt   instance int32 [mscorlib]System.Object::GetHashCode()
IL_0018:  pop
IL_0019:  ret
Run Code Online (Sandbox Code Playgroud)

编辑:为了完整性,我应该指出,int.GetHashCode()简单的正文return this;,正如Raymond Chen在上面的评论中指出的那样,简单地将枚举转换成一个int足以获得哈希码的内容.