IEquatable和刚刚重写Object.Equals()之间有什么区别?

我希望我的Food类能够testing什么时候它等于Food另一个实例。 我将在后面的列表中使用它,并且我想使用它的List.Contains()方法。 我应该实现IEquatable<Food>还是重写Object.Equals() ? 来自MSDN:

此方法通过使用默认的相等比较器来确定相等性,如T(对象列表中值的types)的对象实现的IEquatable.Equals方法所定义的。

所以我的下一个问题是:.NET框架的哪些函数/类使用Object.Equals() ? 我应该首先使用它吗?

主要原因是性能。 当在.NET 2.0中引入generics时,他们能够添加一些整洁的类,如List<T>Dictionary<K,V>HashSet<T>等。这些结构大量使用GetHashCodeEquals 。 但对于价值types这需要拳击。 IEquatable<T>让一个结构实现一个强types的Equals方法,所以不需要装箱。 因此,在使用generics集合的值types时性能会好得多。

引用types没有多less好处,但是IEquatable<T>实现可以避免从System.Object IEquatable<T> ,如果它经常被调用,那么它们可能会有所不同。

正如在Jared Parson的博客上提到的 ,你仍然必须实现对象覆盖。

根据MSDN :

如果实现IEquatable(T),则还应该重写Object.Equals(Object)和GetHashCode的基类实现,以使其行为与IEquatable(T).Equals方法的行为一致。 如果重写Object.Equals(Object),那么在调用类中的静态Equals(System.Object,System.Object)方法时,也会调用重写的实现。 这可以确保Equals方法的所有调用返回一致的结果。

所以看起来两者之间没有真正的function差别,只能根据class级的使用情况来调用。 从性能的angular度来看,它更好的使用通用版本,因为不存在与其相关的装箱/拆箱处罚。

从逻辑的angular度来看,实现界面也更好。 重写对象并不能告诉任何人你的类实际上是可以等同的。 重写可能只是一个无所事事的类或浅层实现。 明确地使用接口说:“嘿,这个东西对于平等检查是有效的!” 这只是更好的devise。

用一个实际的例子来扩展Josh的说法。 给Josh +1,我正要在我的答案中写下同样的内容。

 public abstract class EntityBase : IEquatable<EntityBase> { public EntityBase() { } #region IEquatable<EntityBase> Members public bool Equals(EntityBase other) { //Generic implementation of equality using reflection on derived class instance. return true; } public override bool Equals(object obj) { return this.Equals(obj as EntityBase); } #endregion } public class Author : EntityBase { public Author() { } } public class Book : EntityBase { public Book() { } } 

这样,我有可重用的Equals()方法,为我所有的派生类开箱即用。