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>
等。这些结构大量使用GetHashCode
和Equals
。 但对于价值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()方法,为我所有的派生类开箱即用。