.net中的对象比较

是否与CLR的观点有任何不同,实现IEqualityComparer与覆盖在IEqualityComparer使用的属性的==运算符? 如果是这样,你什么时候用另一个?

编辑

好吧,Hashtable的实现所使用的IEqaulityComparer确实有意义 – 当我发布问题时,它已经脱离了我的脑海。 那么IEnumerable的Linq的扩展呢? 这是否意味着.net在执行这些扩展方法时会构建一个Hashtable?

IEqualityComparerequal ,等于对象(实例方法),但是EqualityComparer用于装饰,例如在linq中你想要特定的不同:

personList.OrderBy(p=>p.ID).Distinct(new MyEqualityComparer())

  class MyEqualityComparer: IEqualityComparer { public bool Equals(Person p1, Person p2) { if (p1.Age == p2.Age) return true; return false; } public int GetHashCode(Person p) { return p.Id.GetHashCode(); } } 

但对于人来说是平等的:

 public class Person { public int ID{get;set;} public int Age{get;set;} public override bool Equals(object o) { //do stuff } } 

您可以通过IEqualityComparer进行任意数量的修饰,但是您无法通过实例方法执行此操作(您可以编写personList.Distinct(new AnotherComparer),…)

IEqualityComparer由Hashtable , NameValueCollection和OrderedDictionary类使用,以支持您的类型的“相等”的自定义定义。 这就是它提供GetHashCode()的原因,它本身与平等无关。

如果您不提供IEqualityComparer ,则上面提到的类将默认为Object.Equals() ,它实现了引用相等性 。 在该上下文中不会调用重载的operator ==

编辑:一些LINQ的扩展方法确实将IEqualityComparer作为参数,但原理保持不变:如果未指定该参数,该方法将最终比较引用,而不是值,并且不会调用operator ==

IEqualityComparer用于例如Dictionary

它与覆盖==运算符完全不同,因为实际上Dictionary (以及通常使用的IEqualityComparer )不会对==运算符进行任何调用。

最多,您可以比较“实现IEqualityComparer ”与“覆盖GetHashCodeEquals方法”,因为它们实际上是两种方式来获得相同的东西(我会说它们与我相同)。