一个人如何检索枚举的哈希码,而不拳击呢? [英] How does one retrieve the hash code of an enumeration without boxing it?

查看:188
本文介绍了一个人如何检索枚举的哈希码,而不拳击呢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果一个人保存一个聚合类型内的枚举,人们可能要包括该类型的哈希代码中(假设一个典型的由素数散列函数乘)。如果一个人只是调用 SomeEnum.GetHashCode(),现在看来,JIT盒实例,即使在发布版本。



剖析这显示了我的申请时间的10%花在拳击枚举内的各种的GetHashCode 功能。



几个值类型实施 IEquatable 或类似的接口,它允许调用的GetHashCode 作为一个静态方法;这就避免了拳击。但 System.Enum 不提供的GetHashCode 的静态超载。有计算,应使用的代码的某些手段,但能避免拳击


解决方案


你可以转换为基本类型的枚举(通常 INT 除非枚举定义另有指定),并使用该类型的覆盖的GetHashCode()方法。



<预类=郎-CS prettyprint-覆盖> 枚举TestEnum
{
的Test1 ,
的Test2
}

TestEnum T = TestEnum.Test1;
((INT)T).GetHashCode(); //没有拳击
t.GetHashCode(); //拳击

下面是IL此代码:



<预类=郎-CS prettyprint-覆盖> 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:呼叫实例INT32 [mscorlib程序] System.Int32 :: GetHashCode的()
IL_000c:$流行b $ b IL_000d:ldloc.0
IL_000e:箱ConsoleApplication1.Program / TestEnum
IL_0013:callvirt例如INT32 [mscorlib程序] System.Object的:: GetHashCode的()
IL_0018:弹出
IL_0019:RET

编辑:为了完整起见,我要指出的是, 正文int.GetHashCode()只是返回这一点; ,从而雷蒙德陈指出,在评论上述,只需铸造枚举一个 INT 是不够好,获得的哈希码。


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?

解决方案

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.

这篇关于一个人如何检索枚举的哈希码,而不拳击呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆