如何检索枚举的哈希码而不将其装箱?
本文关键字:哈希码 何检索 检索 枚举 | 更新日期: 2023-09-27 17:49:38
如果枚举存储在聚合类型中,则可能希望将其包含在该类型的散列代码中(假设是典型的"乘以素数"散列函数)。如果只调用SomeEnum.GetHashCode()
,则JIT会将实例装箱,即使在发布版本中也是如此。
分析显示,我的应用程序大约有10%的时间花在各种GetHashCode
函数内的装箱枚举上。
几个值类型实现IEquatable
或类似的接口,这允许调用GetHashCode
作为静态方法;这样就避免了拳击。但是System.Enum
不提供GetHashCode
的静态过载。有没有一种计算代码的方法可以避免装箱?
可以转换为枚举的底层类型(通常是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在上面的评论中指出的那样,简单地将enum转换为int
就足以获得哈希码。