如何在C#中覆盖接口的equals运算符==?

时间:2009-12-10 14:50:03

标签: c# interface

我定义了以下界面

public interface IHaveAProblem
{
    string Issue { get; set; }
}

这是IHaveAProblem的实现

public class SomeProblem : IHaveAProblem
{
    public string Issue { get; set; }

    public override bool Equals(object obj)
    {
        SomeProblem otherObj = obj as SomeProblem;

        if (otherObj == null)
        {
            return false;
        }

        return this.Issue == otherObj.Issue;
    }

    public override int GetHashCode()
    {
        return base.GetHashCode();
    }

    public static bool operator ==(SomeProblem rhs, SomeProblem lhs)
    {
        // Null check
        if (Object.ReferenceEquals(rhs, null) || Object.ReferenceEquals(lhs, null))
        {
            if (Object.ReferenceEquals(rhs, null) && Object.ReferenceEquals(lhs, null))
            {
                // Both are null.  They do equal each other
                return true;
            }

            // Only 1 is null the other is not so they do not equal
            return false;
        }

        return rhs.Equals(lhs);
    }

    public static bool operator !=(SomeProblem rhs, SomeProblem lhs)
    {
        // Null check
        if (Object.ReferenceEquals(rhs, null) || Object.ReferenceEquals(lhs, null))
        {
            if (Object.ReferenceEquals(rhs, null) && Object.ReferenceEquals(lhs, null))
            {
                // Both are null.  They do equal each other
                return false;
            }

            // Only 1 is null the other is not so they do not equal
            return true;
        }

        return !rhs.Equals(lhs);
    }
}

当我使用该对象时,我可以得到== compare的正确结果。

SomeProblem firstTest = new SomeProblem()
    {
        Issue = "Hello World"
    };

SomeProblem secondTest = new SomeProblem()
    {
        Issue = "Hello World"
    };

// This is true
bool result = firstTest == secondTest;

然而,当我尝试比较接口时,它正在进行内存比较而不是运算符==在SomeProblem上

IHaveAProblem firstProblem = new SomeProblem()
    {
        Issue = "Hello World"
    };

IHaveAProblem secondProblem = new SomeProblem()
    {
        Issue = "Hello World"
    };

是否可以让接口在SomeProblem上使用==而不是内存比较?

我知道我可以做一个firstProblem.Equals(secondProblem)并获得正确的结果,但是我正在创建一个框架工作,我不知道它最终是如何使用的。我以为==会正常工作。

4 个答案:

答案 0 :(得分:26)

运算符==是静态的。您无法在C#中为接口定义静态方法。此外,对于所有运算符,至少有一个参数类型需要与它所定义的类具有相同的类型,因此:接口没有运算符重载:(

您可以做的是使用抽象类 - 并在那里定义运算符。同样,运算符可能不是虚拟的(因为静态方法不能是虚拟的......)

[编辑,理由见评论。]

答案 1 :(得分:4)

IIRC(我可能在这里错了),C#接口不允许运算符重载。

但在这种情况下,没关系。 ==运算符通常映射到引用相等。听起来你想要值相等,这意味着你想强制它们覆盖.Equals()(以及.GetHashCode())函数。您可以通过让您的界面继承自IEquatable()

来实现

答案 2 :(得分:2)

我知道,这是一个老问题,但提供的所有示例都显示了如何比较两个类实例,没有人指出如何比较两个接口实例。

在某些情况下,这是比较接口的DRYest方法。

public interface IHaveAProblem
{
    string Issue { get; set; }
}

public class IHaveAProblemComparer : IComparer<IHaveAProblem>, IEqualityComparer<IHaveAProblem>
{
    public int Compare(IHaveAProblem x, IHaveAProblem y)
    {
        return string.Compare(x.Issue, y.Issue);
    }

    public bool Equals(IHaveAProblem x, IHaveAProblem y)
    {
        return string.Equals(x.Issue, y.Issue);
    }

    public int GetHashCode(IHaveAProblem obj)
    {
        return obj.GetHashCode();
    }
}

<强>使用吗

IHaveAProblemComparer comparer = new IHaveAProblemComparer();

List<IHaveAProblem> myListOfInterfaces = GetSomeIHaveAProblemObjects();
myListOfInterfaces.Sort(comparer); // items ordered by Issue

IHaveAProblem obj1 = new SomeProblemTypeA() { Issue = "Example1" };
IHaveAProblem obj2 = new SomeProblemTypeB() { Issue = "Example2" };

bool areEquals = comparer.Equals(obj1, obj2); // False

答案 3 :(得分:0)

您是否尝试过实施IComparable?

像这样:

public interface IHaveAProblem : IComparable
{
    string Issue { get; set; }
}

然后在课程的实施中:

public class SomeProblem : IHaveAProblem
{
    public string Issue { get; set; }

    ...

    public int CompareTo(object obj)
    {
        return Issue.CompareTo(((SomeProblem)obj).Issue);
    }
}

请注意,这仅适用于比较SomeProblem的两个实例,而不是IHaveAProblem接口的任何其他实现。

不确定是否可能发生NullReferenceException。