ValueType.GetHashCode の奇抜さを掘り下げる: 変化しない可能性のある値
ValueType.GetHashCode のネイティブ実装方法をめぐる陰謀() は値の型のハッシュ コードを計算することは否定できません。特定の例とその予期せぬ結果を調べて、この謎を解明しましょう。
次の構造の 2 つのインスタンスを考えてみましょう:
struct TheKey { public int id; public string Name; }
Name フィールドに個別の値を代入すると、それらのハッシュ コードが期待されます。違うこと。しかし、出力では驚くべき現実が明らかになります。
var k1 = new TheKey(17, "abc"); var k2 = new TheKey(17, new string(new[] { 'a', 'b', 'c' })); Console.WriteLine("hash1={0}", k1.GetHashCode()); Console.WriteLine("hash2={0}", k2.GetHashCode()); // Output: // hash1=346948941 // hash2=346948941
文字列参照が異なるにもかかわらず、k1 と k2 は両方とも同じハッシュ コードを生成します。
メカニズムの公開
ValueType.GetHashCode() のネイティブ実装は、驚くほど複雑なメカニズムを通じて動作します。主に、構造体に参照型参照またはフィールド ギャップが含まれているかどうかを決定します。両方の条件が存在しない場合、値のすべてのビットに対して効率的なビットごとの XOR 演算が実行され、すべてのフィールドが効率的にハッシュ コードに結合されます。ただし、このアプローチは普遍的に適用できるわけではありません。
参照型またはギャップが存在する場合、コードはフィールドごとの走査を開始し、使用可能なフィールド (値型または null 以外のオブジェクト) を検索します。参照。見つかると、このフィールドのハッシュ コードがメソッド テーブル ポインタと XOR 演算されて、最終的なハッシュ コードが形成されます。
謎が明らかに
この例では、使用可能なフィールドはたまたま id です。文字列フィールドは、値が変化しても無視され、k1 と k2 の両方が同じ ID を持つことになり、その結果、同じハッシュ コードになります。
結論
この型破りな動作を理解すると、ハッシュ コード計算用の値の型を慎重に作成することの重要性が強調されます。 CLR のデフォルト実装のみに依存しないようにすることが最も重要です。ハッシュ コードの計算を明示的に定義することで、開発者は値の型に対するハッシュ コードの一意性と一貫性を確保できます。
以上が構造体内の異なる文字列参照に対して同じ ValueType.GetHashCode() の結果が発生するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。