设置总是错误的IEqualityComparer的正确方法是什么?

本文关键字:方法 是什么 错误 IEqualityComparer 设置 | 更新日期: 2023-09-27 18:31:11

我有一个案例,两个对象可以以许多不同的方式进行比较以实现相等。例如:

public class HeightComparer : IEqualityComparer<Person> {
   public bool Equals(Person x, Person y) {
       return x.Height.Equals(y.Height);
   }
   public int GetHashCode(Person obj) {
       return obj.Height;
   }
}

我将这些比较器用于各种方法Dictionary<Person,Person>(IEqualityComparer<Person>)。您将如何制作一个保证每个人都是独一无二的比较器?我想出了以下内容,但它运行缓慢,因为 GetHashCode() 方法通常返回相同的值。

public class NullPersonComparer : IEqualityComparer<Person> {
   public bool Equals(Person x, Person y) {
       return false; // always unequal
   }
   public int GetHashCode(Person obj) {
       return obj.GetHashCode();
   }
}

我可以从GetHashCode(Person obj)返回相同的 0 值,但它填充字典的速度仍然很慢。

编辑

下面是一个用例:

 Dictionary<Person, Person> people = new Dictionary<Person, Person>(comparer);
 foreach (string name in Names)
 {
     Person person= new Person(name);
     Person realPerson;
     if (people.TryGetValue(person, out realPerson))
     {
         realPerson.AddName(name);
     }
     else
     {
         people.Add(person, person);
     }
  }

设置总是错误的IEqualityComparer<T>的正确方法是什么?

如果类型没有覆盖EqualsGetHashCode方法,则它们的默认实现(从 object )执行您想要的操作,即根据其标识而不是其值提供相等性。 如果需要,可以使用EqualityComparer<Person>.Default来获取使用这些语义的IEqualityComparer

如果 Equals 方法已被重写以提供某种值语义,但您不希望这样做,您需要标识语义,那么您可以在自己的实现中使用object.ReferenceEquals

public class IdentityComparer<T> : IEqualityComparer<T>
{
    public bool Equals(T x, T y)
    {
        return object.ReferenceEquals(x, y);
    }
    public int GetHashCode(T obj)
    {
        return System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode(obj);
    }
}