オブジェクトをハッシュコードで比較できるようにしたい。
たとえば、1 つはオブジェクト自体であり、もう 1 つはシリアル化 (バイナリ) されてから復元されたバージョンのオブジェクトです。
シリアル化された (バイナリ) オブジェクトにハッシュを保存するにはどうすればよいですか?
オブジェクトをハッシュコードで比較できるようにしたい。
たとえば、1 つはオブジェクト自体であり、もう 1 つはシリアル化 (バイナリ) されてから復元されたバージョンのオブジェクトです。
シリアル化された (バイナリ) オブジェクトにハッシュを保存するにはどうすればよいですか?
ハッシュ コードをシリアル化する必要があるのはなぜですか? 代わりに、2 つのオブジェクトを値に基づいて比較できるように、オブジェクト内にGetHashCode()
との適切な実装を提供する必要があります。2 つのオブジェクトが等しい場合、それらのハッシュ コードは一致する必要があります。Equals()
したがって、オブジェクトを逆シリアル化したら、それを使用GetHashCode()
して他のオブジェクトと比較できます。2 つのハッシュ コードが一致するという事実は、等しいかどうかを判断するのに十分ではなく、まだ異なる場合があることに注意してくださいEquals()
。等しいかどうかを判断するには、 の適切な実装を呼び出す必要があります。
オブジェクト内のカスタム フィールドを比較するだけで、完全な比較がコストがかかりすぎる場合 (つまり、大きなバイナリ配列)MD5CryptoServiceProvider.ComputeHash()
は、フィールドで MD5 ハッシュを生成し (つまり、 を使用)、それをオブジェクト自体に格納するのが理にかなっている場合があります。その後、他のオブジェクト プロパティと同じようにシリアル化されます。
用心してください!
.Net オブジェクトの既定の HashCode は、プログラムのランタイム インスタンス間で頻繁に変更されます。
つまり、プログラムが objectA
をハッシュコード付きでディスクにシリアライズした場合、プログラムは終了し、後で再起動され、ディスクからオブジェクトをデシリアライズします (または実行時にA
同一のオブジェクトを作成します)。保存されたものとは異なるハッシュコードA
を持っています。
これは、デフォルトのハッシュコードがオブジェクトのガベージ コレクター情報から取得されるためです。新しいプログラム インスタンスでは、GC の情報が異なるため、ハッシュコードも異なります。
独自の をGetHashCode
作成すると、プロセス間で一貫したハッシュコードを作成できます。しかし、ここで注意しなければならない落とし穴があります。
どのオブジェクトがどのオリジナルからシリアライズおよびデシリアライズされたかを知るために使用できる情報はありますか? その場合は、GetHashCode() をオーバーライドして、その情報に基づいてハッシュ コードを計算できます。
そうでない場合は、新しく作成された各オブジェクトに UUID を割り当てることで、合成的に生成できる可能性があります。再構築されたオブジェクトが同じ UUID を持つように、その値を他のデータと一緒にシリアル化します。その後、単純に GetHashCode() をオーバーライドして、その UUID のハッシュ コードを返すことができます。(探しているものが参照等価性の一種の修正版である場合は、これでうまくいくはずです。)