何时使用IEquatable和为什么

Jac*_*ada 42 c# iequatable

我只是不明白这一点 - IEquatable给你带来了什么?

我可以看到它有用的唯一原因是创建泛型类型并强制用户实现并编写一个好的equals方法.

我错过了什么

Cor*_*ius 40

来自MSDN:

IEquatable(T)接口由泛型集合对象,如使用Dictionary(TKey, TValue),List(T)以及LinkedList(T)在这种方法中,作为平等测试时Contains,IndexOf,LastIndexOf,和Remove.

IEquatable<T>实施将需要对这些类少投,结果会比标准稍微快一点object.Equals将被以其他方式使用方法.作为示例,请参阅两种方法的不同实现:

public bool Equals(T other) 
{
  if (other == null) 
     return false;

  return (this.Id == other.Id);
}

public override bool Equals(Object obj)
{
  if (obj == null) 
     return false;

  T tObj = obj as T;  // The extra cast
  if (tObj == null)
     return false;
  else   
     return this.Id == tObj.Id;
}
Run Code Online (Sandbox Code Playgroud)

  • 有没有人知道如果你在使用泛型集合时没有实现iequtalable会发生什么? (3认同)
  • @ChloeRadshaw 然后它将使用引用等于引用类型。 (2认同)

naw*_*fal 34

我很惊讶这里没有提到最重要的原因.

IEquatable<> 主要是针对结构引入的,原因有两个:

  1. 对于值类型(读取结构),非泛型Equals(object)需要装箱.IEquatable<>让结构实现强类型Equals方法,这样就不需要装箱.

  2. 对于结构体,Object.Equals(Object)(通过重写版本System.ValueType)的默认实现通过使用反射来比较类型中每个字段的值来执行值相等性检查.当实现者覆盖结构中的虚拟Equals方法时,目的是提供一种更有效的方法来执行值相等性检查,并可选择将结果基于结构的一个或多个属性的子集.

两者都提高了性能.

引用类型(读取类)没有那么多受益.在IEquatable<>实现中让你避免从铸造System.Object,但是这是一个很琐碎的增益.我仍然希望IEquatable<>为我的类实现,因为它在逻辑上使得intent明确.

  • @Backwards_Dave 是肯定的,但是 1,`IEquatable` 使意图更加清晰(考虑一个引用的 lib 类,它的源你没有),2,你可以将你的结构传递给接受 `IEquatable` 或对 `IEquatable` 有通用约束的方法T&gt;`, 3, 最重要的是,像 `Contains` 等各种集合操作的大多数实现都不会调用你自定义的 `Equals`(它们都检查类型是否实现了 `IEquatbale`,否则调用基础 `ValueType.Equals`) . (2认同)

Mar*_*ann 10

我使用IEquatable<T>了很多,虽然从纯粹的技术角度来看,它并没有给我带来任何特别的好处.覆盖System.Object.Equals可以为您提供相同的功能.

但是,我喜欢实施的明确IEquatable<T>.我使用的概念实体值对象领域驱动设计颇多,并使用IEquatable<T>特别的值对象,只是因为它标志着一个类型具有明确的平等.

  • 不要忘记使用IEquatable <T>意味着你不必忍受使用System.Object.Equals获得的装箱/拆箱. (7认同)
  • 只有密封类型才能实现`IEquatable <T>`.如果`IEquatable <XBase>`执行除了链接到`Object.Equals(Object)`以外的任何操作,则重新定义相等性的任何派生类型`XDerived`必须重新实现`IEquatable <XBase>`并将其参数转换为`XDerived `.如果不这样做会导致一个对象在例如"Dictionary <XBase,TValue>"中表现不正常. (4认同)