重写等于和GetHash

Chr*_*s G 5 c#

我已经读过,当你在类/对象上重写Equals时,你需要覆盖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);
        }


    }
Run Code Online (Sandbox Code Playgroud)

现在给出以下内容:

 public static Dictionary<Person, Person> ObjDic= new Dictionary<Person, Person>();
 public static Dictionary<int, Person> PKDic = new Dictionary<int, Person>();
Run Code Online (Sandbox Code Playgroud)

不会覆盖GetHashCode会影响上面的两个Dictionary吗?我基本上问的是GetHashCode是如何生成的?如果我仍在寻找PKDic中的对象,我将能够根据PK找到它.如果我想覆盖GetHashCode怎么会这样做呢?

SLa*_*aks 4

您应该始终覆盖GetHashCode.

ADictionary<int, Person>将在没有 的情况下运行GetHashCode,但是一旦您调用 LINQ 方法(如DistinctGroupBy),它将停止工作。

顺便说一下,请注意,您实际上也没有覆盖Equals。该方法与继承自的IEquatable.Equals方法不一样。尽管如果类实现了该接口,默认情况下将使用该接口,但您仍然应该重写,因为其他代码可能不会。virtual bool Equals(object obj)ObjectIEqualityComparer<T>IEquatable<T>Equals

在你的情况下,你应该重写EqualsGetHashCode像这样:

public override bool Equals(object obj) { return Equals(obj as Person); }
public override int GetHashCode() {
    return FirstName.GetHashCode() ^ LastName.GetHashCode();
}
Run Code Online (Sandbox Code Playgroud)