简体   繁体   中英

How do I override the equals operator == for an Interface in C#?

I have defined the following interface

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

And here is the implementation of the 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);
    }
}

When I use the object I can get the correct results for the == compare.

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

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

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

However when I try to compare the interfaces it is doing a memory compare rather than the operator == on SomeProblem

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

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

Is it possible have the interface use the == on SomeProblem rather than a memory compare?

I know I can do a firstProblem.Equals(secondProblem) and get the proper result, however I am creating a frame work and I will not know how it is used in the end. I thought == would work correctly.

The operator == is static. You cannot define static methods for interfaces in C#. Also, for all operators at least one of the argument types needs to be of the same type as the class it is defined in, therefore: No operator overloading for interfaces :(

What you CAN do is use an abstract class instead - and define the operator there. Again, the operator may NOT be virtual (since static methods cannot be virtual...)

[Edited, reason see comment.]

IIRC (and I could be wrong here), C# interfaces don't allow operator overloading.

But in this case that's okay. The == operator normally maps to reference equality. It sounds like you want value equality, and that means you want to force them to override the .Equals() (and consequently also .GetHashCode() ) functions. You do that by having your interface inherit from IEquatable() .

I konw, this is an old question, but all examples provided show how to compare two class instances, and no one points out how to compare two interface instances.

In some cases, this is the DRYest way to compare interfaces.

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();
    }
}

Usage?

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

Have you tried implementing IComparable?

Like this:

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

And then in the implementation of the class:

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

    ...

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

Note that, this works only when you compare two instances of SomeProblem, but not any other implementations of the IHaveAProblem interface.

Not sure if there could occur a NullReferenceException.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM