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()は単に isであることを指摘しておく必要がありますreturn this;。そのため、上記のコメントで Raymond Chen が指摘したように、enum を an にキャストするだけでint、ハッシュ コードを取得するのに十分です。

于 2012-12-28T01:23:28.020 に答える