2011-07-08 9 views
2

辞書のContainsKey()メソッドが機能しません - どうすれば "GetHashCode()"をオーバーライドして動作させることができますか?キーが単純なプリミティブ型でないときにContainsKey()を使用する

+1

これはどの言語ですか? –

+0

あなたの鍵の種類は何ですか?その構造は何ですか? – Manatherin

+1

自分のタイプのキークラス、または他の誰かのクラスですか?メソッドをオーバーライドする方法を知っていますか? GetHashCodeに関するいくつかの根拠については、http://blogs.msdn.com/b/ericlippert/archive/2011/02/28/guidelines-and-rules-for-gethashcode.aspxを参照してください。 –

答えて

6

等価を示すには、GetHashCode()Equals()の両方を上書きする必要があります。たとえば、次のように

public sealed class MyType : IEquatable<MyType> { 
    private readonly int foo; 
    private readonly string bar; 
    public int Foo { get { return foo; } } 
    public string Bar { get { return bar; } } 

    public MyType(int foo, string bar) { 
     this.foo = foo; this.bar = bar; 
    } 
    public bool Equals(MyType other) { 
     if(other == null) return false; 
     return other.foo == this.foo && other.bar == this.bar; 
    } 
    public override bool Equals(object other) { 
     return Equals(other as MyType); 
    } 
    public override int GetHashCode() { 
     int result = 29; 
     result = result * 13 + foo.GetHashCode(); 
     result = result * 13 + (bar == null ? 0 : bar.GetHashCode()); 
     return result; 
    } 
} 

IEquatable<T>は完全に任意であるが、それは箱を避ける構造体のために特に有用であること。注意:平等を定義する部分が不変の場合、それは命を救うでしょう。

+0

はbool Equals(オブジェクトother)とGetHashCodeをオーバーライドする必要があります – Manatherin

+0

彼は必ずしもメソッドをオーバーライドする必要はありませんが、等価比較関数が提供されるDictionaryコンストラクタのオーバーロードがあります。 –

+0

@Manatherinはい、彼らはすべきです - 私の悪い! –

2

、あなたのアイテムのクラスに必要なメソッド(GetHashCode()Equals())をオーバーライドする方法がありません場合は、あなたがIEqualityComparer<T>の比較を実行するために提供することができ、辞書のコンストラクタがあります。その後、元のクラスに触れることなく、これらのメソッドの実装を提供することができます。

class FooEqualityComparer : IEqualityComparer<Foo> 
{ 
    public bool Equals(Foo x, Foo y) 
    { 
     // implement Equals between x and y 
    } 

    public int GetHashCode(Foo obj) 
    { 
     // implement GetHashCode for obj 
    } 
} 

class Foo 
{ 
    // fields, properties, methods, etc. 
} 

// a dictionary that can use Foo's as keys 
var myFooDict = new Dictionary<Foo, object>(new FooEqualityComparer()) 
{ 
    // ... 
}; 
// use it like normal 
if (myFooDict.ContainsKey(someFoo)) // the comparison will be handled by the comparer provided from the constructor 
{ 
    // do stuff... 
} 
関連する問題