internal source中有一个这样的构造器public HashSetEqualityComparer(IEqualityComparer<T> comparer),但是它是内部构造的,所以我不能使用它。

默认情况下,HashSet<T>.CreateSetComparer()仅使用将应用EqualityComparer<T>.Default的无参数构造函数。

有没有一种方法可以使HashSetEqualityComparer<T>与选择的IEqualityComparer<T>,而无需从源代码中复制代码?

最佳答案

我认为最好的解决方案是使用SetEquals。它可以完成您所需的工作,并且完全与HashSetEqualityComparer相同,但是它将考虑其比较集中定义的所有自定义比较器。

因此,在您要使用HashSet<T>作为字典键的特定情况下,您需要实现一个使用IEqualityComparer<HashSet<T>>SetEquals并“借用” HashSetEqualityComparer.GetHashCode()的引用源:

public class CustomHashSetEqualityComparer<T>
    : IEqualityComparer<HashSet<T>>
{
    public bool Equals(HashSet<T> x, HashSet<T> y)
    {
        if (ReferenceEquals(x, null))
            return false;

        return x.SetEquals(y);
    }

    public int GetHashCode(HashSet<T> set)
    {
        int hashCode = 0;

        if (set != null)
        {
            foreach (T t in set)
            {
                hashCode = hashCode ^
                    (set.Comparer.GetHashCode(t) & 0x7FFFFFFF);
            }
        }

        return hashCode;
    }
}


但是,是的,这有点痛苦,因为无法直接创建利用自定义比较器的SetEqualityComparer,但是不幸的是,恕我直言,这是由于现有实现的一个错误,而不是缺少所需的重载。正如上面的代码所示,CreateSetComparer()没有理由不能返回实际使用其比较对象集的比较器的IEqualityComparer

如果我有声音,CreateSetComparer()根本不是静态方法。显然,至少可以预见,将使用当前集合的比较器创建返回的任何比较器。

07-24 20:29