在C#中,Jon Skeet使用IEquatable<>
来覆盖重载Equals()
操作。
public sealed class Pair<T1, T2> : IEquatable<Pair<T1, T2>>
{
public bool Equals(Pair<T1, T2> other)
{
//...
}
}
他说我们这样做是为了“提供强类型的API,以避免不必要的执行时间检查”。
避免执行哪些执行时间检查?更重要的是,实现接口如何实现强类型API?
我可能在本书的背景下遗漏了一些东西。我认为接口通过多态性让我们重用代码。我也理解它们适合编程为抽象而不是具体类型。这就是我所知道的。
答案 0 :(得分:5)
默认Equals
method需要object
作为参数。因此,在实现此方法时,您必须在代码中进行运行时检查,以确保此对象的类型为Pair
(在您比较这两个之前):
public override bool Equals(Object obj) {
// runtime type check here
var otherPair = obj as Pair<T1, T2>;
if (otherPair == null)
return false;
// comparison code here
...
}
IEquatable<T>
的Equals
方法需要Pair<T1,T2>
作为类型参数。因此,您可以避免检查您的实施,从而提高效率:
public bool Equals(Pair<T1, T2> other)
{
// comparison code here
...
}
Dictionary<TKey, TValue>
,List<T>
和LinkedList<T>
等类非常聪明,可以在其元素上使用IEquatable<T>.Equals
而非object.Equals
(如果可用)(请参阅{ {3}})。
答案 1 :(得分:3)
在这种情况下,他提供了Object.Equals
的强类型版本,它将替换可能如下所示的代码:
public override bool Equals(object other)
{
// The following type check is not needed with IEquatable<Pair<T1, T2>>
Pair<T1, T2> pair = other as Pair<T1, T2>;
if (pair != null)
{
// <-- IEquatable<Pair<T1, T2>> implementation
}
else
{
return base.Equals(other);
}
}
答案 2 :(得分:2)
IEquatable<T>
接口提供Equals
方法的强类型实现,而不是Equals
中接收System.Object
的{{1}}方法。< / p>
答案 3 :(得分:0)
我认为Jon说“强类型”谈论泛型。
我没有找到非通用的IEquitable
界面,但存在IComparable<T>
与IComparable
。
答案 4 :(得分:0)
为了公平对待Skeet(尽管他很快就会参加),他确实花时间讨论第2.2.1节中“强类型”的含义。
在你的问题的上下文中(我的版本中的第85页)),我认为他的意思是默认的Equals方法(以对象作为参数)遵循实现接口的强类型Equals方法。 / p>