0

以下に示すようなカスタムコレクションがあります

public class CustomCollection<T>:IEnumerable<T>, IEnumerator<T>
{
    int size = 0;
    int current = 0;
    int position = -1;
    CustomComparer<T> cmp = new CustomComparer<T>();

    T[] collection = null;
    public CustomCollection(int sizeofColl)
    {
        size = sizeofColl;
        collection = new T[size];
    }

    public void Push(T value)
    {
        if (!collection.Contains(value, cmp))
            collection[current++] = value;
    }

    public T Pop()
    {
        return collection[--current];
    }        

    IEnumerator<T> IEnumerable<T>.GetEnumerator()
    {
        return (IEnumerator<T>)this;
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        throw new NotImplementedException();
    }

    public T Current
    {
        get { return collection[position]; }
    }

    public void Dispose()
    {

    }

    object System.Collections.IEnumerator.Current
    {
        get { throw new NotImplementedException(); }
    }

    public bool MoveNext()
    {
        position++;
        if (position >= collection.Length)
            return false;
        else
            return true;
    }

    public void Reset()
    {
        throw new NotImplementedException();
    }
}

今、私は IEqualityComparer と共に以下のような Person クラスのコレクションを持ちたいと思っています

 public class Person
{
    public string Name { get; set; }
    public int ID { get; set; }       
}

public class CustomComparer<T>:IEqualityComparer<T>    {


    public bool Equals(T x, T y)
    {
        Person p1 = x as Person;
        Person p2 = y as Person;
        if (p1 == null || p2 == null)
            return false;
        else
            return p1.Name.Equals(p2.Name);
    }

    public int GetHashCode(T obj)
    {
        Person p = obj as Person;
        return p.Name.GetHashCode();
    }
}

コレクションに対して次の操作を実行すると、 GetHashCode() ではなく Equals メソッドのみが呼び出されるのはなぜですか?

  CustomCollection.CustomCollection<Person> custColl = new CustomCollection<Person>(3);
        custColl.Push(new Person() { Name = "per1", ID = 1 });
        custColl.Push(new Person() { Name = "per2", ID = 2 });
        custColl.Push(new Person() { Name = "per1", ID = 1 });

または、 GetHashCode を呼び出すコードを作成するにはどうすればよいですか?

4

1 に答える 1

2

これは、次の行に関連しています。

if (!collection.Contains(value, cmp))

ベクトルまたはシーケンスに対するテスト ( のように見えるEnumerable.Containsため) を呼び出す目的はありませんGetHashCode()。これは、データがハッシュ バケットまたはその他の最適化された構造にグループ化されている場合に役立ちますが、ここでのデータは単純な一連の値です。Equalsメソッドを呼び出す必要がある場合は、 を呼び出すよりも呼び出したほうがよいかもしれませんGetHashCode()。ハッシュが同じ場合でも呼び出す必要があるからですEquals(ハッシュコードは非等価を示しますが、等価を示すことはできません)。したがって、オブジェクトごとに正確に 1 つのメソッドを呼び出すか、オブジェクトごとに少なくとも 1 つのメソッドを呼び出し、場合によってはオブジェクトごとに 2 つのメソッドを呼び出す選択です。明らかに最初の方が望ましいです。

データが aDictionary<Person, ...>または aHashSet<Person>である場合、使用されると予想GetHashCode()されます。

于 2013-03-07T10:09:29.903 に答える