2011-02-09 10 views
3

私はIntPtrとenumに基づいてメンバーを格納できる場所を確保する必要があります。言い換えれば、IntPtrとenum(sp_playlist_typeという名前)の同じマッチを取得した場合、私は同じ結果を得ることができる必要がありますが、それだけで(それも重要です)。私は2つを含む構造体を作成し、GetHashCode()をオーバーライドすると思ったが、その後、2つの数値の重複を作成しないハッシュアルゴリズムが必要で、同じ結果が毎回生成される2つの数字が存在する。辞書のキーとして2つのフィールドの組み合わせを使用する

+4

標準の間違いです。ハッシュは同じ番号を再現する必要があります。ユニークである必要はありません。 Equals()はアイデンティティーを処理します。 –

+0

@ハンス: 'Equals'は' Dictionary 'から呼び出されますか? – Alxandr

+0

すでに述べたように、ハッシュコードは一意である必要はありません。ただし、等しい2つのオブジェクトは、互いに同じハッシュコードを持つ必要があります。 – Pedro

答えて

6

私はタプルのGetHashCodeメソッドと平等がalredy作成されている方法に基づいて、あなたが持っていると思う:

Dictionary<Tuple<IntPtr, YourEnum>, YourResultType> 

あなたはもちろんの.NET 4.0で提供されます。

7

、私はこれは実際には真実ではありません二つの数字

のための複製を作成しないハッシュ・アルゴリズムを必要とするだろう。 GetHashCode()を上書きする必要がありますが、衝突する可能性があります。ハッシュコード内の衝突を最小限に抑え、排除する必要はありません。

これは実際にはかなり簡単です。一般的なオプションは、構造体の両方のメンバーのハッシュコード、またはそれに類似したものの排他的論理和を使用することです。

+1

Reed、私が間違っている場合は私を修正しますが、私はTuple <>クラスを信じてGetHashCodeをメンバーのハッシュコードの組み合わせに(そして同様に)同様にオーバーライドします。辞書、何でも>? –

+1

@James:Tuple は、カスタム構造体を作成したくない場合は正常に動作します。私はしばしば自分自身の構造体を書くつもりです。なぜなら、それはもっとはっきりしているからです。 –

+0

真、本当です。私はタプルやカスタム構造体が好きかどうかを前後に行きます。 –

1

簡単な方法は、文字列をキーとして使用することです。この文字列で両方の値を結合します。たとえば:

mydic.add(GetKey(ptr, playlist_type), myvalue); 
+0

プレイリストはそれが大きなリストではないことを示唆していますが、それはまさにハイパフォーマンスな解決策ではありませんか? –

+0

これは、文字列の変換のためにかなり遅くなります。これは最高のハッシュでもありません。 –

+0

ハッシュコードを作成して正しい配布を保証するのが一般的なパターンです。このようにして、新しい構造体またはクラスを作成してGetHashCodeメソッドをオーバーライドしてキーとして使用する必要はありません。それはすべてのフレームワークのバージョンで有効です。 – Borja

0

それは他の人がそれを一意にするための要件が​​ない言及しているので、GetHashCodeメソッドをオーバーライドすることは厳密には必要ありません。

private string GetKey(IntPrt prt, sp_playlist_type playlist_type) 
{ 
    return string.format("{0}#{1}", prt, type) 
} 

がそれを使用するには、のようなものを使用します。

パフォーマンス上の理由から、構造体のEqualsをオーバーライドすることが望ましい場合があります。as described in MSDN

この場合はrecommended to override GetHashCodeです。この場合、おそらくIntPtrと列挙型(64ビットシステム上のIntPtrのLS 32ビット)のXORです。

+0

Equalsをオーバーライドする場合、GetHashCodeをオーバーライドする必要があります。 – Pedro

+0

もしそれが強く推奨されているということを意味するのであれば、私は同意します - それは私が作ろうとしていることです。しかし、フレームワークはあなたに義務付けておらず、構造体のデフォルトと同等のEquals実装を作成すると、そうすることなく取り除くことができます。 – Joe

+0

あなたがそれをやっていなければ、あなたは辞書に適切なアクセスを保証することはできません。 (つまり、あなたのコードには深刻な欠陥があります)。同等の実装を作成することについては、その場合、あなたは本当にEqualsを上書きしていないと言います。 – Pedro

関連する問題