2012-01-19 3 views
8

同じ文字列に対して同じハッシュコードを与える関数はありますか?文字列のユニークなハッシュコードを生成するにはどうすればいいですか?

2つの異なる文字列(同じ内容のもの)を作成する際に問題がありますが、そのハッシュコードが異なるため、Dictionaryで正しく使用されていません。

私がGetHashCode()が機能していることを知りたいのですが、Dictionaryはキーが文字列のときに使用します。

public override int GetHashCode() 
{ 
    String str = "Equip" + Equipment.ToString() + "Destiny" + Destiny.ToString(); 
    return str.GetHashCode(); 
} 

をしかし、それは同じである文字列の内容にもかかわらず、このコードを使用してインスタンスごとに異なる結果をもたらすだ:

私はこのような鉱山を構築しています。

+5

Equalsはその後のようになります。 – Joey

+1

あなたは内容が等しいと確信していますか? String.GetHashCodeのドキュメントでは、ハッシュコードが等しい文字列に対して同じであることが明確に記載されています。http://msdn.microsoft.com/en-us/library/system.string.gethashcode.aspx –

+0

String .GetHashCodeは、プログラムを再起動すると異なるハッシュを返します。 – Tsabo

答えて

13

あなたのタイトルはあなたの体は別の何か(一貫したハッシュコード)を要求し、一つのこと(ユニークハッシュコード)を要求します。

あなたが主張する:(しかし、同じ内容の)2つの異なる文字列を作成するときに、私はトラブルを抱えている

、そのハッシュコードが異なるため、正しく辞書で使用されていません。

文字列真にの内容が同じ場合、それは起こりません。あなたの診断は何とか間違っています。例えばUnicodeの「ヌル」の文字を末尾に、あなたの文字列でない文字を確認してください:ここで

string text1 = "Hello"; 
string text2 = "Hello\0"; 

text1text2は、いくつかの文脈で同じように印刷することができるが、私は、彼らが異なるハッシュコードを持っていると思います願っていたいです。ハッシュコードがが一意であることが保証されていないとが...わずか2 可能ハッシュコードがないがあることができることを

GetHashCodeから戻ったが、以上の2つの可能な異なる文字列。あなたはどこにでも持続ハッシュコードすべきではない -

も同じ内容が同じであっても実行可能で、異なる実行に同じハッシュコードを生成することを保証ないであることに注意してください。たとえば、32ビットの.NET 4と64ビットの.NET 4 CLRでは、文字列に対して異なるハッシュコードが生成されると考えられます。しかし、値がDictionaryに正しく格納されていないというあなたの主張は、これが単一のプロセス内にあることを示唆しています。すべてと一致するはずです。

コメントに記載されているとおり、間違ってEqualsを上書きしている可能性があります。私はまた、ハッシュコードを構築するあなたのアプローチが素晴らしいではないことをお勧めしたいと思います。私たちは、EquipmentDestinyの種類が何であるかわからないが、私はあなたのようなものを使用する必要がありお勧めしたい:私は、通常はハッシュコードに使用するアプローチだ

public override int GetHashCode() 
{ 
    int hash = 23; 
    hash = hash * 31 + Equipment.GetHashCode(); 
    hash = hash * 31 + Destiny.GetHashCode(); 
    return hash; 
} 

を。文字列が実際には同じだった場合、ハッシュコードは、あまりにも、同じだろう

public override bool Equals(object other) 
{ 
    // Reference equality check 
    if (this == other) 
    { 
     return true; 
    }   
    if (other == null) 
    { 
     return false; 
    } 
    // Details of this might change depending on your situation; we'd 
    // need more information 
    if (other.GetType() != GetType()) 
    { 
     return false; 
    } 

    // Adjust for your type... 
    Foo otherFoo = (Foo) other; 

    // You may want to change the equality used here based on the 
    // types of Equipment and Destiny 
    return this.Destiny == otherFoo.Destiny && 
      this.Equipment == otherFoo.Equipment; 
} 
+0

機器と運命は両方とも列挙型です – RagnaRock

+1

@RagnaRock:右 - この場合は問題ありません。これはクラスか構造体ですか?それがクラスなら、それは封印されていますか?いずれにせよ、私はあなたが疑わしいハッシュの不一致を再現できることを疑う。 –

+0

問題がequalsメソッドにあった、私はそれをオーバーライドしなくてはならないと思ったが、いったんそれが期待通りに機能した。 – RagnaRock

関連する問題