Как вы переопределяете оператор == при использовании интерфейсов вместо реальных типов? - PullRequest
1 голос
/ 15 июня 2010

У меня есть такой код:

Как мне реализовать оператор ==, чтобы он вызывался, когда переменные имеют интерфейс IMyClass?

public class MyClass : IMyClass
{
    public static bool operator ==(MyClass a, MyClass b)
    {
        if (ReferenceEquals(a, b))
            return true;

        if ((Object)a == null || (Object)b == null)
            return false;

        return false;
    }

    public static bool operator !=(MyClass a, MyClass b)
    {
        return !(a == b);
    }
}

class Program
{
    static void Main(string[] args)
    {
        IMyClass m1 = new MyClass();
        IMyClass m2 = new MyClass();

        MyClass m3 = new MyClass();
        MyClass m4 = new MyClass();

        Console.WriteLine(m1 == m2); // does not go into custom == function. why not?
        Console.WriteLine(m3 == m4); // DOES go into custom == function
    } 
}

Ответы [ 3 ]

6 голосов
/ 15 июня 2010

Ключ в том, что вы не переопределяете оператор - вы перегружаете это.

Нет оператора, определенного для

operator ==(IMyClass x, IMyClass y)

так что компилятору нечего вызывать.Он не может вызвать

operator ==(MyClass x, MyClass y)

, так как не знает, что m1 и m2 на самом деле будут ссылаться на экземпляр MyClass.

Насколько я знаю, естьнет способа реализовать оператор, который будет использоваться для интерфейсов - в конце концов, несколько реализаций могут предоставить свой собственный, только для одной точки возможной двусмысленности.

Лично я несколько опасаюсь пытаться говорить о равенстведля незакрытых типов для начала - равенство и наследование не очень хорошо сочетаются.Конечно, это вдвойне относится к интерфейсам :) Возможно, вам лучше всего реализовать соответствующий IEqualityComparer<IMyClass> и использовать его вместо этого.

0 голосов
/ 15 июня 2010

Посмотрите в принятом ответе на этот вопрос: == vs. Object.Equals (объект) в .NET

Разница между идентичностью и семантическим равенством. Переопределение == предназначено для структур, которые должны быть «одинаковыми», потому что они имеют одинаковые значения, поскольку структуры копируются по значению и поэтому никогда не являются ссылками на один и тот же объект.

Равен используется для семантической проверки равенства значений для ссылочных типов. По умолчанию обе операции одинаковы.

0 голосов
/ 15 июня 2010

Попробуйте сделать оператор == виртуальным.

...