Можно ли определить поведение == для ссылки на интерфейс?

Если интерфейс наследует IEquatable, реализующий класс может определить поведение метода Equals. Можно ли определить поведение операций ==?

public interface IFoo : IEquatable  
{}  

public class Foo : IFoo  
{  
    // IEquatable.Equals  
    public bool Equals(IFoo other)  
    {  
        // Compare by value here...
    }  
}

Чтобы проверить, что две ссылки IFoo равны, сравнив их значения:

IFoo X = new Foo();  
IFoo Y = new Foo();

if (X.Equals(Y))  
{  
     // Do something  
}

Можно ли заставить if (X == Y) использовать метод Equals для Foo?


person Leander    schedule 04.11.2008    source источник


Ответы (2)


Нет - вы не можете указывать операторы в интерфейсах (в основном потому, что операторы статичны). Компилятор определяет, какую перегрузку == вызывать, основываясь исключительно на их статическом типе (т. е. полиморфизм не задействован), и интерфейсы не могут указать код, чтобы сказать «вернуть результат вызова X.Equals (Y)».

person Jon Skeet    schedule 04.11.2008
comment
И это то, чего мне больше всего не хватает при использовании дженериков, о... и специализации. - person Coincoin; 04.11.2008

Нет, так как интерфейс не может содержать операторские функции. Решением было бы сделать IFoo абстрактным классом вместо интерфейса:

abstract class IFoo : IEquatable<IFoo> 
{
    public static bool operator ==(IFoo i1, IFoo i2) { return i1.Equals(i2); }
    public static bool operator !=(IFoo i1, IFoo i2) { return !i1.Equals(i2); }
    public abstract bool Equals(IFoo other);
}

class Foo : IFoo
{
    public override bool Equals(IFoo other)
    {
        // Compare
    }
}

Конечно, при этом вы теряете гибкость, обеспечиваемую интерфейсами.

person Luc Touraille    schedule 04.11.2008