等于覆盖与 IEquatable<>

Equals override vs. IEquatable<>

对于我来说,我的 WPF 绑定无法为 RibbonComboBoxSelectedItem 属性.

正常工作

然后我开始阅读有关 .NET 如何比较项目的内容。我的理解是,在某些情况下,它比较实际的指针。在这种情况下,从数据库中加载一个新的相等的值,例如,它可能不被认为是相等的。

然后我开始考虑为我的类型明确实现 Equals。但是,这似乎有点令人困惑,因为我至少可以实现两个不同的版本。

下面的代码表明我可以覆盖 object.Equals,或者我可以实现 IEquatable<>。其实下面的代码都实现了,测试表明都调用了.

public class TextValuePair : IEquatable<TextValuePair>
{
    public string Text { get; set; }
    public int Value { get; set; }

    public override bool Equals(object obj)
    {
        if (obj == null || !(obj is TextValuePair))
            return false;
        return Value == (obj as TextValuePair).Value;
    }

    public override int GetHashCode()
    {
        return Value;
    }

    public bool Equals(TextValuePair obj)
    {
        Debug.Assert(obj != null);
        if (obj == null)
            return false;
        return Value == obj.Value;
    }
}

谁能帮助我理解需要什么才能避免 .NET 库例程根据具有相同值的指针比较我的对象是否等效? Equals两个版本真的有必要实现吗?

正如 msdn 所指出的,如果您正在实施 IEquatable<T>,您仍然需要覆盖 Equals,因为它仍将使用签名 Equals(System.Object, System.Object) 和 yhe override 应该与 IEquatable<T> 实现的方法一致。

与 Arno 在评论中显示的 question about the difference between iequatable and just overriding object equals 一样,当需要对集合进行操作以优化它们时使用 IEquatable<T>,不再需要装箱,而是直接调用等于特定类型。

你有两个选择:

如果您在程序中使用集合时对性能感兴趣,可以继续实现这两个 Equals 方法;

您可以删除 IEquatable<T> 并只覆盖 Equals 以简化您的代码。

此外,无论何时覆盖 Equals,您也应该始终覆盖 GetHashCode