Интерфейс C# не может содержать операторов

Может ли кто-нибудь объяснить, почему интерфейсы С# не могут содержать операторы?

Спасибо.


person Jake    schedule 06.07.2011    source источник


Ответы (2)


C# операторы должны быть статическими. Интерфейсы по определению применяются к экземплярам. Не существует механизма, требующего, чтобы тип реализовывал статические члены.

EDIT:
Начиная с C# 8.0, как вы можете видеть, здесь теперь можно определять локальные методы в интерфейсах и реализовывать их внутри самого интерфейса, например позволяя создавать перегрузки методов, не требуя, чтобы реализации также заботились об этих перегрузках, когда они могут просто предоставить дополнительный параметр перегрузке, которую необходимо реализовать.
Наряду с этим вы также можете определять операторы в интерфейсах, хотя они должны быть статическими, поэтому они должны быть реализованы в интерфейсе.

Таким образом, в C# 8.0 будет напечатано «это работает в C# 8», за которым следует «1»:

interface ICanAdd
{
    int Value { get; }

    public static int operator+ (ICanAdd lvalue, int rvalue)
    {
        Console.WriteLine("this works in C# 8");
        return lvalue.Value + rvalue;
    }
}

class Add : ICanAdd
{
    public int Value => 0;
}

class Program
{
    static void Main(string[] args)
    {
        ICanAdd foo = new Add();
        var x = foo + 1;
        Console.WriteLine(x);
    }
}

Изменить 23 января 2020 г.

Вы не можете добавлять операторы преобразования, равенства или неравенства в интерфейсы, иначе вы столкнетесь со следующей ошибкой:

CS0567 Интерфейсы C# не могут содержать операторы преобразования, равенства или неравенства.

person dkackman    schedule 06.07.2011
comment
На ум приходят методы расширения, но методы расширения нельзя использовать как операторы или свойства. - person Jeffrey Hantin; 07.07.2011
comment
Но есть ли причина, по которой интерфейсы нельзя расширить, включив в них статические методы и операторы? - person cordialgerm; 07.07.2011
comment
@pickles - нет жесткой и быстрой причины, по которой язык/компилятор не мог бы создать такую ​​конструкцию (я думаю, что на самом деле могут быть некоторые из них - возможно, Delphi, и это можно несколько имитировать (статические виртуальные методы в наименее) в C++ с использованием шаблонов (T::Method())) - C# решил этого не делать. - person dkackman; 07.07.2011
comment
Во втором ответе на этот пост есть комментарий о том, почему в С# этого нет. stackoverflow.com/questions/259026/ - person dkackman; 07.07.2011
comment
Извините, что оживляю старую тему, но поскольку оператор/свойство скобки индексации не являются статическими, их можно использовать в интерфейсе. - person Greg Kramida; 17.04.2012
comment
@GregKramida Разница в C# заключается в том, что индексатор технически не является оператором, как в C++. Это синтаксический сахар языка, который сводится к методу экземпляра get_Item в IL. В спецификации грамматики индексаторы и операторы объявляются отдельно и по-разному. msdn.microsoft.com/en-us/library /aa664812(v=vs.71).aspx - person dkackman; 26.08.2015
comment
Спасибо @DavideCannizzo за указание на то, что это изменилось в C# 8. - person dkackman; 23.12.2019
comment
Кто-нибудь знает, почему существует ограничение на операторы равенства? - person Mike Marynowski; 28.07.2020

Вы не можете определять операторы для интерфейсов, потому что класс может реализовывать несколько интерфейсов. Представьте, если бы этот код был возможен:

static class Fooness {
  public static operator==(IFoo l, IFoo r) { ... }
}
static class Barness {
  public static operator==(IBar l, IBar r) { ... }
}

public class Foobar : IFoo, IBar { ... }

Какая реализация == должна преобладать при использовании на экземплярах Foobar? (И прежде чем ответить, представьте, что IFoo/Fooness происходят из одной DLL, а IBar/Barness — из другой).

Даже если бы вы могли каким-то образом разрешить эту двусмысленность, мы должны спросить себя, будет ли это вообще хорошей идеей. Я надеюсь, что приведенное выше показывает, что с оператором == это очень плохая идея. Автор оператора == для каждого интерфейса предполагает, что единственными важными аспектами объекта, когда дело доходит до сравнения, являются те, которые охватываются интерфейсом. Иногда это может быть правдой, но в целом это не так.

Вот почему разумно использовать операторы только в закрытых классах. Только тогда вы можете быть уверены, что ваш оператор знает об объекте достаточно для корректной работы.

person Steve Benz    schedule 01.11.2019