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

Dav*_*rab 17 c# interface

我已经定义了以下界面

public interface IHaveAProblem
{
    string Issue { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

这是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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

// This is true
bool result = firstTest == secondTest;
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试比较接口时,它正在进行内存比较而不是SomeProblem上的operator ==

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

IHaveAProblem secondProblem = new SomeProblem()
    {
        Issue = "Hello World"
    };
Run Code Online (Sandbox Code Playgroud)

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

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

gha*_*.st 28

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

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

[编辑,理由见评论.]

  • 也许我得到最后一段错误,但我认为这是错误的.我会说:"运算符的默认实现(在引用类型和接口上)表现为`Object`提供的`ReferenceEquals`方法.当然不是`Equals`方法,它本身也默认引用相等(对于引用类型) ,如果没有被派生类覆盖).而且,结构没有默认的运算符==,尽管你可以定义一个. (2认同)

T-m*_*oty 6

提供的所有示例都展示了如何比较两个类实例,但没有人指出如何比较两个接口实例。

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

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

用法?

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
Run Code Online (Sandbox Code Playgroud)


Joe*_*orn 5

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

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