How does one retrieve the hash code of an enumeration without boxing it?

左心房为你撑大大i 提交于 2019-12-05 22:03:25

问题


If one has an enumeration stored inside an aggregate type, one might want to include that inside the type's hash code (assuming a typical "multiply by primes" hash function). If one just calls SomeEnum.GetHashCode(), it appears that the JIT boxes the instance, even in release builds.

Profiling this shows some 10% of the time of my application spent boxing enumerations inside various GetHashCode functions.

Several value types implement IEquatable or similar interfaces, which allows calling GetHashCode as a static method; which avoids the boxing. But System.Enum doesn't provide the static overload of GetHashCode. Is there some means of computing the code that should be used but that avoids the boxing?


回答1:


You could cast to the underlying type of the enum (usually int unless the enum definition specifies otherwise) and use that type's overridden GetHashCode() method.

enum TestEnum
{
    Test1,
    Test2
}

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

Here is the IL for this code:

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

Edit: For completeness, I should point out that the body of int.GetHashCode() is simply return this;, so as Raymond Chen pointed out in a comment above, simply casting the enum to an int is good enough to obtain a hash code.



来源:https://stackoverflow.com/questions/14063313/how-does-one-retrieve-the-hash-code-of-an-enumeration-without-boxing-it

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!