HashSet<T>.CreateSetComparer() 无法指定 IEqualityComparer<T>,是否有替代方案?

Dav*_* S. 4 c# hashset iequalitycomparer

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

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

有没有办法获得一个HashSetEqualityComparer<T>选择IEqualityComparer<T>,而不需要从源代码中复制代码?

InB*_*een 6

我认为最好的解决方案是使用SetEquals. 它以完全相同的方式完成您需要的工作HashSetEqualityComparer,但它将考虑其比较集中定义的任何自定义比较器。

因此,在您想要使用 aHashSet<T>作为字典键的特定场景中,您需要实现一个IEqualityComparer<HashSet<T>>利用SetEquals并“借用”参考源的an 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,是的,这是一个小痛苦,因为没有办法直接创建一个SetEqualityComparer利用自定义比较器的 ,但恕我直言,这种不幸的行为更多地是由于现有实现的错误而不是缺乏所需的重载;没有理由CreateSetComparer()不能返回一个IEqualityComparer实际使用其比较集的比较器的值,如上面的代码所示。

如果我有声音在里面,那CreateSetComparer()根本就不是静态方法。那么很明显,或者至少可以预见,无论返回什么比较器都将使用当前集的比较器创建。