2

この質問とジョンの答えは、これが存在することさえあることに気づいたので、興味を持って Visual Studio を起動しました。


MSDN ページの 1 つの例をたどってから、独自の小さな例を作成しました。それは次のとおりです。

public class Person : IEquatable<Person>
{
    public string IdNumber { get; set; }
    public string Name { get; set; }

    public bool Equals(Person otherPerson)
    {
        if (IdNumber == otherPerson.IdNumber)
            return true;
        else
            return false;
    }

    public override bool Equals(object obj)
    {
        if (obj == null) 
            return base.Equals(obj);

        if (!(obj is Person))
            throw new InvalidCastException("The Object isn't of Type Person.");
        else
            return Equals(obj as Person);
    }

    public override int GetHashCode()
    {
        return IdNumber.GetHashCode();
    }

    public static bool operator ==(Person person1, Person person2)
    {
        return person1.Equals(person2);
    }

    public static bool operator !=(Person person1, Person person2)
    {
        return (!person1.Equals(person2));
    }
}

だから私はいくつかの質問があります:

  1. Equals メソッドがカスタムの等価性を適切に処理する場合、GetHashCode メソッドもオーバーライドする必要があるのはなぜですか?

  2. 以下のようなものを比較する場合、Equals と GetHashCode のどちらの比較子が使用されますか?

.

static void Main(string[] args)
{
    Person sergio = new Person() { IdNumber = "1", Name = "Sergio" };
    Person lucille = new Person() { IdNumber = "2", Name = "Lucille" };

    List<Person> people = new List<Person>(){
        sergio,
        lucille
    };

    Person lucille2 = new Person() { IdNumber = "2", Name = "Lucille" };
    if (people.Contains(lucille2))
    {
        Console.WriteLine("Already exists.");
    }

    Console.ReadKey();
}
  1. オペレーターメソッドは正確に何をしますか? ある種のブードゥー教の黒魔術が行われているようです。
4

4 に答える 4

7

Equalsメソッドがカスタムの等式をうまく処理できる場合、GetHashCodeメソッドもオーバーライドする必要があるのはなぜですか?

Dictionary<T, U>これにより、のキーになる、。に格納するなど、ハッシュを介して機能するコレクションでタイプを使用できますHashSet<T>

以下のようなものを比較する場合、どちらの比較器が使用されますか、EqualsまたはGetHashCode?

GetHashCodeは比較には使用されず、ハッシュ操作にのみ使用されます。Equalsが常に使用されます。

演算子メソッドは正確に何をしますか?ある種のブードゥー黒魔術がそこで起こっているように見えます。

==これにより、タイプの2つのインスタンスで直接使用できます。これがないと、タイプがクラスであるかどうかを参照して比較することになり、タイプ内の値では比較できません。

于 2011-04-09T22:14:52.410 に答える
3

GetHashCodeの目的は、ハッシュテーブルのバランスを取ることであり、同等性を判断することではありません。ハッシュテーブルのメンバーを検索する場合、チェックされるハッシュバケットはハッシュコードによって決定され、オブジェクトがバケット内にあるかどうかは等式によって決定されます。そのため、GetHashCodeは平等に同意する必要があります。

詳細については、このテーマに関する私の記事を参照してください。

http://ericlippert.com/2011/02/28/guidelines-and-rules-for-gethashcode/

于 2011-04-09T22:15:10.210 に答える
1

GetHashCodeとEqualsは2つの非常に異なるものです。Equals平等を決定します。GetHashCodeハッシュマップに適したハッシュコードを返しますが、同等性を保証するものではありません。したがって、平等の問題では、平等Equalsを決定する方法になります。

GetHashCodeなどのハッシュセットを対象としていDictionaryます。辞書でアイテムを検索するときは、ハッシュコードのエントリと一致し、次にで一致しますEquals

于 2011-04-09T22:14:07.833 に答える
0

GetHashCode は、ハッシュ テーブルを使用する場合にのみMSDN によって使用されます。

平等が必要な場合は、Equals のみを気にします。MSDN は、GetHashCode も実装することを提案しています。これは、遅かれ早かれ、ハッシュのようなオブジェクト (ハッシュ テーブル、ハッシュ マップなど) でオブジェクトを使用する可能性があるためです。

オブジェクトが 1000 バイトで、 2 つのオブジェクトが等しいかどうかをすばやく判断する必要があるとします。(GetHashCode を使用して) ハッシュ キーを計算します。キーが一致しない場合、オブジェクトは異なります。それらが一致する場合、それらが実際に等しいかどうかを確認することはできません.Equal()で検証する必要があります-これはより高価です.

ハッシュ テーブル コレクションは、このアイデアを使用します。

于 2011-04-09T22:26:25.637 に答える