9

如果一个枚举存储在聚合类型中,则可能希望将其包含在类型的哈希码中(假设典型的“乘以素数”哈希函数)。如果只调用SomeEnum.GetHashCode(),则 JIT 似乎将实例装箱,即使在发布版本中也是如此。

对此进行分析表明,我的应用程序大约 10% 的时间花在了各种GetHashCode函数中的装箱枚举上。

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

4

1 回答 1

6

您可以转换为枚举的基础类型(通常int除非枚举定义另有说明)并使用该类型的覆盖GetHashCode()方法。

enum TestEnum
{
    Test1,
    Test2
}

TestEnum t = TestEnum.Test1;
((int)t).GetHashCode(); // no boxing
t.GetHashCode(); // boxing

这是此代码的 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

编辑:为了完整起见,我应该指出的主体int.GetHashCode()是简单的return this;,所以正如 Raymond Chen 在上面的评论中指出的那样,简单地将枚举转换为 anint就足以获得哈希码。

于 2012-12-28T01:23:28.020 回答