为什么我们需要IEqualityComparer和IEqualityComparer<T>接口?

6

'Equal'和'GetHashCode'方法存在于对象类中,而我们的类型继承了对象基类。 直接实现这两个方法和使用IComparer接口有何不同?

如果我们重写对象的Equal和GetHashCode方法,并将其推入哈希表中,它会使用重写的Equal方法吗?

使用IEqualityComparer构造函数新建哈希表有何不同?

2个回答

14
IComparable接口用于需要对对象进行“排序”的情况,并提供一个方法(CompareTo),告诉您两个对象是 <, = 还是 >。使用IEqualityComparer的构造函数允许您提供特定的Equals/GetHashCode,这可以与您的对象定义的不同。通常,Hashtable将使用您的对象覆盖的EqualsGetHashCode(或基本的object EqualsGetHashCode)。
举个例子,标准字符串比较区分大小写("A" != "a"),但您可以创建一个IEqualityComparer帮助类,以便以不区分大小写的方式哈希您的字符串。(技术上说,该类已经存在多个变体:它们被称为StringComparer.InvariantCultureIgnoreCase和所有返回实现IComparerIEqualityComparerIComparer<string>IEqualityComparer<string>StringComparer静态方法中的其他StringComparer对象)
需要注意的是,Hashtable使用可选参数IEqualityComparer,而不是泛型版本的IEqualityComparer<T>,因为Hashtable是预生成的。

1

IComparer 接口(包括泛型和非泛型接口)允许您将两个实例进行比较。

Compare 方法允许您将一个对象本身与另一个实例进行比较。当当前实例为 null 时,您会在这种情况下得到一个 NullReferenceException,因为您在 'null' 实例上调用了 Compare。实现 IComparer 的类可以解决此问题。

因此,当您实现 IComparer 接口时,您将拥有一个具有 'Compare' 方法的类,可以像这样调用它:

public class MyObjectComparer : IComparer<MyObject>
{
    public int Compare( MyObject first, MyObject second )
    {
       // implement logic here to determine whether first is less, greater or equal then second.
    }
}

这允许你做这个:

var c = new MyObjectComparer();
var one = new MyObject();
var two = new MyObject();
c.Compare (one, two);

当您使用指定IEqualityComparer实例的构造函数实例化Hashtable时,这意味着给定的IEqualityComparer将用于确定Hashtable中是否已经存在某个键。
否则,将使用键对象的Compare方法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接