在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()
根本不是静态方法。显然,至少可以预见,将使用当前集合的比较器创建返回的任何比较器。