3

それが私が持っているものです:

class A
{
  // The uniqueness of instance must be detected by this property
  public string Key { get; set; }

  // There are other properties
}

var set = HashSet<A>()

私の一般的な目的は次のとおりです。

  • setコレクション内のインスタンスの ID をKeyプロパティ値で提供する

  • Contain 操作でこのコレクションをできるだけ速く動作させるため

次の質問への回答は、この目的を達成するのに役立つ場合があります。

  1. インスタンスの一意性を決定する必要があるようなメソッドを実行するために使用されるもの: GetHashCode() またはContainsIEquatable ? Addほとんどの場合、HashSet は検索が非常に高速であると宣言されているので、GetHashCode() です。
  2. デフォルトString.GetHashCode()の実装では、2 つの異なる文字列のハッシュの一意性が保証されていないため、パフォーマンスを考慮して一意性を提供するにはどうすればよいですか?
  3. IEquatable は HashSet でまったく使用されていますか?

彼のコレクションは実行時にのみ作成および破棄され、データベースには保存されないことに注意してください

4

1 に答える 1

13

コレクションは通常、 と を使用Object.GetHashCode()Object.Equals()てハッシュ コードを取得し、等価性をチェックします。最も単純なオブジェクトを除いて、一意のハッシュ コードを返すようにする方法はありませんObject.GetHashCode()。ハッシュ コードは 32 ビット幅しかなく、内部状態が 32 ビットを超えるすべてのオブジェクトを一意のハッシュ コードにマップすることはできません。したがってObject.Equals()、ハッシュ コードの衝突が発生した場合に正確な等価性をチェックするために使用されます。

結果として、前述の両方のメソッドを適切な実装でオーバーライドする必要があります。

public override Int32 GetHashCode()
{
    // If this.Key may be null you have to handle this case.
    return this.Key.HashCode();
}

public override Boolean Equals(Object obj)
{
    var other = obj as A;

    return (other != null) && (this.Key == other.Key);
}

あるいは、セットに追加する型のソース コードを制御できない場合などに、HashSet<T>コンストラクターを使用して両方のメソッドを受け入れて外部化することもできます。IEqualityComparer<T>適切なメソッドを使用してインターフェイスを実装するクラスを作成し、このクラスのインスタンスをHashSet<T>コンストラクターに渡すだけです。

于 2013-01-17T19:22:05.827 に答える