RegisterHotKeyとObject.GetHashCode (その2)

前回のエントリではまだもやっとしたままだった

一意性は保障されないと書いてある。
まあ、通常はおとなしくアトムを使えば良いのだが、コードの記者がObject.GetHashCodeを使った意図が気になる。コードの出来からして、単なる手抜きとは思えないのだ。

そこで、今日届いたこの本。
プログラミングMicrosoft .NET Framework 第2版 (マイクロソフト公式解説書)
プログラミングMicrosoft.NET Framework / Jeffrey Richter (著), 吉松 史彰 (翻訳)

実はこの本を購入するのを決めた時から、Object.GetHashCodeに関してどのように書いているかを楽しみにしていた。

(AppDomainの中で)一意なIDを取得したいときには、ObjectのGetHashCodeメソッドを呼び出してはいけません。〜略〜 型でObjectのGetHashCodeメソッドがオーバライドされていたときに、一意のIDを返すことができなくなってしまいます。
プログラミングMicrosoft.NET Framework/「第5章 単純型、参照型、値型」より

なるほどもっともな回答だと思うが、問題はその後。

FCLにはオブジェクトの一意のIDを返すメソッドが定義されています。System.Runtime.CompilerServices名前空間のRuntimeHelperクラスに、publicでstaticなGetHashCodeメソッドが定義されています。〜略〜 このメソッドにこういう名前がついているのは過去の経緯からなのですが、MicrosoftはGetUniqueObjectIDのような名前を付けておくべきでした。
プログラミングMicrosoft.NET Framework/「第5章 単純型、参照型、値型」より

RuntimeHelpersクラスかーー。こいつは気がつかなかったなと思いつつsscli2.0のソースコードで同クラスの実装を覗いてみたところ

public static int GetHashCode(Object o)
{
    return Object.InternalGetHashCode(o);
}

あれれ、なんか見たことあるぞと思って同じくObject.csの同名のインスタンスメソッドを見てみると

public virtual int GetHashCode()
{
    return InternalGetHashCode(this);
}

少なくともsscliのレベルでは両方とも同じメソッドを呼んでいることが判る。
どうやらオーバライドされる事に気をつけさえすれば、GetHashCodeを一意のIDとして使って良いのではないだろうか。
なお、同書にも書いてあるが、Object.GetHashCodeの戻り値が一意であることが保たれているのは、同一AppDomain内だけであるという制限があるのでその点は注意が必要。Remotingを使っている状態などでは、やはり使えないということだ。