dev*_*ium 168 .net c# equality equals iequatable
我希望我的Food类能够在它等于另一个实例时进行测试Food.我稍后会对List使用它,我想使用它的List.Contains()方法.我应该实施IEquatable<Food>还是仅仅覆盖Object.Equals()?来自MSDN:
此方法通过使用默认的相等比较器来确定相等性,由对象的T的IEquatable.Equals方法的实现(列表中的值的类型)定义.
所以我的下一个问题是:.NET框架的哪些函数/类可以使用Object.Equals()?我应该首先使用它吗?
Jos*_*osh 193
主要原因是表现.当泛型介绍.NET 2.0中,他们能够增加一堆整齐班如List<T>,Dictionary<K,V>,HashSet<T>,等这些结构大量使用GetHashCode和Equals.但对于价值类型,这需要拳击.IEquatable<T>让结构实现强类型Equals方法,因此不需要装箱.因此,在使用具有泛型集合的值类型时,性能会更好.
引用类型没有那么多的好处,但IEquatable<T>实现确实可以让你避免一个强制转换,System.Object如果经常调用它会产生影响.
正如Jared Parson的博客所述,您仍然必须实现Object覆盖.
Cod*_*num 45
根据MSDN:
如果实现了
IEquatable<T>,你也应该重写的基类的实现Object.Equals(Object),并GetHashCode让他们的行为与该一致的IEquatable<T>.Equals方法.如果覆盖Object.Equals(Object),则在调用类上的静态Equals(System.Object, System.Object)方法时也会调用重写的实现.这可确保Equals方法的所有调用都返回一致的结果.
所以似乎两者之间没有真正的功能差异,除了可以根据类的使用方式调用其中任何一个.从性能角度来看,最好使用通用版本,因为没有与之相关的装箱/拆箱惩罚.
从逻辑的角度来看,实现界面也更好.覆盖对象并不能真正告诉任何人你的类实际上是等同的.覆盖可能只是一个无用的类或浅实现.使用界面明确地说,"嘿,这个东西对于等式检查是有效的!" 这只是更好的设计.
thi*_*eek 27
通过一个实际的例子来扩展乔希所说的话.+1给Josh - 我的答案也是如此.
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() { }
}
Run Code Online (Sandbox Code Playgroud)
这样,我可以重复使用Equals()方法,该方法适用于所有派生类.