Peer Alignment and GetHash

I read that when you override Equals for a class / object, you need to override GetHashCode.

 public class Person : IEquatable<Person>
    {
        public int PersonId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }

        public Person(int personId, string firstName, string lastName)
        {
            PersonId = personId;
            FirstName = firstName;
            LastName = lastName;

        }

        public bool Equals(Person obj)
        {
            Person p = obj as Person;

            if (ReferenceEquals(null, p)) 
                return false;
            if (ReferenceEquals(this, p)) 
                return true;

            return Equals(p.FirstName, FirstName) && 
                   Equals(p.LastName, LastName);
        }


    }

Now the following is given:

 public static Dictionary<Person, Person> ObjDic= new Dictionary<Person, Person>();
 public static Dictionary<int, Person> PKDic = new Dictionary<int, Person>();

Does GetHashCode overdo it affect both dictionaries above? Basically I ask how is GetHashCode generated? IF I am still looking for an object in PKDic, I can only find it on a PC basis. If I wanted to override GetHashCode, how would I do this?

+5
source share
4 answers

You should always redefine GetHashCode.

A Dictionary<int, Person>will function without GetHashCode, but as soon as you call LINQ methods such as Distinctor GroupBy, it will stop working.

, , Equals. IEquatable.Equals virtual bool Equals(object obj), Object. IEqualityComparer<T> IEquatable<T>, , Equals, .

Equals GetHashCode :

public override bool Equals(object obj) { return Equals(obj as Person); }
public override int GetHashCode() {
    return FirstName.GetHashCode() ^ LastName.GetHashCode();
}
+4

GetHashCode , , .

Dictionary<TKey,TValue> -, , - . , - , , . , , , .

- . , -. , - , , . - , .

- Dictionary Equals , - .

" GetHashCode", . , ( , ). . , .

( ) XOR ( -, ) -. , . , .

+4

GetHashCode() Equals() :

public int GetHashCode()
{
    return (FirstName.GetHashCode()+1) ^ (LastName.GetHashCode()+2);
}


public bool Equals(Object obj)
{
    Person p = obj as Person;

    if (p == null) 
        return false;

    return this.Firstname == p.FirstName && this.LastName == p.Lastname;
}

, GetHashCode() , .Equals().

, .GetHashCode(). .

int ( ) GetHashCode() , (ObjDic) GetHashCode() Person. PKDic , ObjDic , , .

+3
source

This is how I do it. Since the same name is the same for two different people, it makes sense to use a unique identifier (which you already have).

public class Person : IEquatable<Person>
{
  public override int GetHashCode()
  {
    return PersonId.GetHashCode();
  }

  public override bool Equals(object obj)
  {
    var that = obj as Person;
    if (that != null)
    {
      return Equals(that);
    }
    return false;
  }

  public bool Equals(Person that)
  {
    return this.PersonId == that.PersonId;
  }
}

To answer your specific question: this only matters if you use it Personas a key in the collection IDictionary. For example, Dictionary<Person, string>or SortedDictionary<Person, Foo>, but not Dictionary<int, Person>.

+1
source

All Articles