Сравнить 2 интерфейса - PullRequest
       11

Сравнить 2 интерфейса

1 голос
/ 18 февраля 2011
interface I //: IEquatable<I>
{ }

class A : I
{
    static public bool operator !=(A a, I i)
    {
        return !(a == i);
    }

    static public bool operator ==(A a, I i)
    {
        return true;
    }

    public override bool Equals(object obj)
    {
        if (obj is I)
            return this == (I)obj;
        else
            return base.Equals(obj);
    }

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

class B : I
{
    static public bool operator !=(B b, I i)
    {
        return !(b == i);
    }

    static public bool operator ==(B b, I i)
    {
        return false;
    }

    public override bool Equals(object obj)
    {
        if (obj is I)
            return this == (I)obj;
        else
            return base.Equals(obj);
    }

    public override int GetHashCode()
    {
        return base.GetHashCode();
    }
}
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        List<I> iss = new List<I>();
        A a = new A();
        B b = new B();
        iss.Add(a);
        iss.Add(b);

        if (iss[0] == iss[1])
            Console.WriteLine("a == b");
        else
            Console.WriteLine("a != b");

        if (iss[1] == iss[0])
            Console.WriteLine("b == a");
        else
            Console.WriteLine("b != a");
    }
}

Выход

a != b
b != a

Я ожидал

a == b
b != a

Может ли кто-нибудь это объяснить?

Ответы [ 2 ]

1 голос
/ 18 февраля 2011

Я бы установил точку останова в методе Equals () и операторе == каждого класса и посмотрел, что вызывается для оценки каждого выражения.Это явно не то, что вы ожидаете.Я предполагаю, что поскольку I не требует и не может требовать от разработчиков предоставления оператора ==, когда два I сравниваются, как вы делаете, среда выполнения не беспокоит поиск перегруженных операторов и вместо этого прибегает кSystem.Object ==, который выполняет ссылочную проверку.

0 голосов
/ 18 февраля 2011

Простой ответ:

У вас есть List<I>, и вы сравниваете два I друг с другом. Поскольку interface I не реализует (и не может) реализовывать оператор сравнения, объекты сравниваются по ссылке.

Вместо этого вы можете использовать абстрактный базовый класс:

public interface I
{
}

public abstract class AbstractI : I
{
    public static bool operator ==(AbstractI left, I right)
    {
        return left.equals(right); //TODO can be null
    }
    public static bool operator !=(AbstractI left, I right)
    {
        return !left.equals(right);
    }

    protected abstract bool equals(I other);
}

public class A : AbstractI
{
    protected override bool equals(I other)
    {
        //TODO your compare code here
        throw new NotImplementedException();
    }
}

public class B : AbstractI
{
    protected override bool equals(I other)
    {
        //TODO your compare code here
        throw new NotImplementedException();
    }
}


List<AbstractI> l = new List<AbstractI>(){
    new A(),
    new B()
};

var x = l[0] == l[1];
...