将EqualityComparer <T>优先于IEqualityComparer <T>

flo*_*ode 36 .net c#

IEqualityComparer<T>MSDN上的备注部分:

  1. 我们建议您从EqualityComparer <T>类派生而不是实现IEqualityComparer <T>接口,因为EqualityComparer <T>类使用IEquatable <T> .Equals方法而不是Object.Equals方法测试相等性....

    • 我不明白引用的论点,为什么我们宁愿从EqualityComparer<T>类而不是实现派生 IEqualityComparer<T>.它意味着实现的对象IEqualityComparer<T>将使用测试相等性Object.Equals,但是IEqualityComparer<T>当我们不想使用Object.Equals或测试相等性时,它不是实现的全部要点IEquatable<T>.Equals.

    • 它还暗示如果我们派生自EqualityComparer<T>,那么派生类将使用IEquatable<T>.Equals方法测试相等性.同样,这不是从EqualityComparer<T>我们不想使用Object.Equals或测试相等性的时候得到的全部内容IEquatable<T>.Equals(因为EqualityComparer<T>.Default已经使用Object.Equals或测试过IEquatable<T>.Equals)?

  2. ......这是符合的包含,的IndexOf,LastIndexOf和Remove字典<TKEY的,TValue>中类和其他泛型集合的方法.

    • 我假设.NET库中的大多数集合测试默认的元素相等(即当用户不IEqualityComparer<T>向这些集合提供自己的自定义对象时)通过调用IEquatable<T>.EqualsObject.Equals(取决于类型的元素是否T实现IEquatable<T>)来实现EqualityComparer<T>.Default.

    • 为什么这些集合(在测试默认相等时)不直接调用IEquatable<T>.EqualsObject.Equals直接调用EqualityComparer<T>.Default类?

Jef*_*ado 27

关于你的第一个问题:

它说的实际上是无用的,因为IEqualityComparer<T>界面的两种方法都标记为抽象.它们都没有"默认"实现,无论如何你都必须覆盖它.如果有的话,他们在这里提供的"推理"听起来更像是比较器可以做什么的指导方针,与实际做的无关.

查看EqualityComparer<T>该类的公共/受保护接口,只有一种兑换质量,它实现了非通用IEqualityComparer接口.我认为他们的意思是说他们推荐它,因为EqualityComparer<T>实际上实现了非通用IEqualityComparer接口,这种方式可以在需要非泛型比较器的地方使用.

IComparer<T>备注部分更有意义:

我们建议您从Comparer <T>类派生而不是实现IComparer <T>接口,因为Comparer <T>类提供IComparer.Compare方法的显式接口实现和获取默认比较器的Default属性物体.

我怀疑它应该说类似的东西Comparer<T>但是有些想法混杂在一起并最终得到了不完整的描述.


关于你的第二个问题:

在图书馆中找到的馆藏的主要目标是尽可能灵活.获得这种方法的一种方法是允许通过提供IComparer<T>Comparer<T>进行比较来自定义比较其中对象的方法.如果没有提供默认比较器的实例,那么获取默认比较器的实例比直接进行比较要容易得多.反过来,这些比较器可能包含调用恰当比较的必要逻辑.

例如,比较器可以确定是否IComparer.CompareDefault并且调用IEqualityComparer<T>对象或以其他方式使用IComparer<T>.更好地封装在比较器中,而不是在集合代码中可能重复.

此外,如果他们想要IEqualityComparer<T>直接回调,他们将不得不添加一个约束T,这将使这个调用成为可能.这样做会使其灵活性降低,并且不利于首先提供比较器的好处.

  • @flock:我的错误,我认为评论中的问题与原问题中的问题相同.要回答这个问题,我想说你想要比较那些不一定实现`IEquatable <T>`的东西但是想要指定比较方式的东西,你实现了`IEqualityComparer <T>`接口.不一定是因为你不想使用`IEquatable <T> .Equals`提供的实现. (2认同)