字典中的字典上的IEqualityComparer

本文关键字:字典 IEqualityComparer | 更新日期: 2023-09-27 18:33:20

我想创建一个Dictionary<DateTime, Dictionary<APerson, AVisit>>结构,我想在第二个字典上提供一个IEqualityComparer,该字典将APerson作为键

如果我只有内部字典,那将是

var f = new Dictionary<APerson, AVisit>(new PersonEqualityComparer());

但是我找不到构造函数在声明中提供它。我是否必须在每个子Dictionary<APerson, AVisit>声明中传递它,或者是否可以指示母结构始终具有指定的IEqualityComparer

字典中的字典上的IEqualityComparer

我必须在字典的每个子声明中传递它吗

是的,

因为外部字典的值是字典。因此,每次您在此外部字典中插入值时,您实际上是您在其他地方实例化的一些字典。因此,您可以在实例化相等比较器的位置提供相等比较器。

我必须在字典的每个子声明中传递它吗

是的(如果您的意思是Dictionary<APerson, AVisit>的每个实例)。

或者是否可以指示母结构始终具有指定的IEqualityComparer?

不。

但是,您可以重新组织。而不是

Dictionary<DateTime, Dictionary<APerson, AVisit>>

为什么不呢

Dictionary<Tuple<DateTime, APerson>, AVisit>

然后,您可以只提供一个实现的实例

IEqualityComparer<Tuple<DateTime, APerson>>

您甚至可以将Tuple<DateTime, APerson>替换为自定义类型。

若要解决必须在子字典的每个实例上指定 IEqualityComparer<APerson> 实例的问题,您可以做的是在APersonIEquatable<APerson>,如此 MSDN 文档中所示。 在 Equals 方法中,可以编写实际的比较逻辑或调用已定义的IEqualityComparer<APerson>实例。 Dictionary将检测到对象实现了IEquatable<APerson>,并将其用作进行比较的默认值。

如果采用此路线,建议在PersonEqualityComparer上有一个Default字段(声明为静态只读),以便在Equals方法中不必每次都创建新实例。 这样你就有类似于以下内容的东西:

public class PersonEqaulityComparer : IEqualityComparer<APerson>
{
    public static readonly Default = new PersonEqualityComparer();
}
public class APerson : IEquatable<APerson>
{
    public bool Equals(APerson other)
    {
        return PersonEqualityComparer.Default.Equals(this, other);
    }
    public override bool Equals(object other)
    {
        return ((IEquatable<APerson>)this).Equals(other as APerson);
    }
    public override int GetHashCode()
    {
        return PersonEqualityComparer.Default.GetHashCode(this);
    }
}