Может ли кто-нибудь объяснить, почему интерфейсы С# не могут содержать операторы?
Спасибо.
Может ли кто-нибудь объяснить, почему интерфейсы С# не могут содержать операторы?
Спасибо.
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# не могут содержать операторы преобразования, равенства или неравенства.
Вы не можете определять операторы для интерфейсов, потому что класс может реализовывать несколько интерфейсов. Представьте, если бы этот код был возможен:
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 — из другой).
Даже если бы вы могли каким-то образом разрешить эту двусмысленность, мы должны спросить себя, будет ли это вообще хорошей идеей. Я надеюсь, что приведенное выше показывает, что с оператором == это очень плохая идея. Автор оператора == для каждого интерфейса предполагает, что единственными важными аспектами объекта, когда дело доходит до сравнения, являются те, которые охватываются интерфейсом. Иногда это может быть правдой, но в целом это не так.
Вот почему разумно использовать операторы только в закрытых классах. Только тогда вы можете быть уверены, что ваш оператор знает об объекте достаточно для корректной работы.