Comments 52
В C# 8 появилась возможность реализации члена интерфейса по умолчанию:
Наконец-то, давно пора!
Интерфейсы могут содержать виртуальные члены
Ну вот и пришли к тому, что давно было в абстрактных классах C++. И стоило велосипед под названием "интерфейсы" изобретать?!
Они ещё немного подумают и добавят и поля ;) и назовут это новой "революционной" возможностью C# 9 или 10.
// default implementations
public void sendNotification(string mes)
{
Console.WriteLine(mes);
}
// override sendNotification
public void sendNotification()
{
Console.WriteLine("New implementation");
}
Сигнатура метода другая. Здесь нет переопределения.
За наводку спасибо, но уж лучше разбираться по docs.microsoft.com и оригинальному репозиторию от Microsoft.
Считаю что определение членов в интерфейсе — почти полностью бесполезная и полностью разрушающая понятие "интерфейс". Это как дырка, через которую можно взаимодействовать с объектом.
В том-то и дело, что нельзя. Нет доступа к внктреннему состоянию объекта — переменных нет.
Потому что в 99.99% случаях при имплементации IEnumerable приходится писать два GetEnumerator, сейчас же можно сделать реализовать не обобщенный интерфейс в обобщенном.
И ещё очень надеюсь что наконец то ICollection станет реализовывать IReadonlyCollection. (Это брейкинг ченж без дефолтных имплементаций). Лишь бы они на это не забили.
private:
protected:
public:
что бы не писать перед каждым методомprotected
для интерфейса: protected interface ICommand
Ну как то так это должно выглядеть. И все нормально если каждый член имеет реализацию по умолчанию (каждый член будет иметь модификатор доступа интерфейса): void exec();
{
return 1;
}
void sendNotification(string mes)
{
Console.WriteLine(mes);
}
Вот только в случае с абстрактными членами возникает сумятится:
protected interface ICommand
{
void exec();
{
return 1;
}
void sendNotification(string mes)
{
Console.WriteLine(mes);
}
void newMethod();
}
Каким должен быть модификатор доступа у «newMethod»?..
Как по мне это все вносит лишнюю сложность)
Если бы меня спросили, как я это вижу — я бы ответил «с использованием директив препроцессора».
Пишем что-то типа
#Public
string Property1 {get; set;}
void Method1() {}
#EndPublic
#Private
int field1;
void Method2{}
#EndPrivate
public event Action PublicEvent();
class A : I {
public:
string Property1 {get; set;}
void Method1() {}
private:
int field1,field2,field3;
void Method2() {}
public override(I): // и даже так
void I_method1() {}
...
Почти наверняка никогда. И хорошо: группировка методов по признаку публичности/приватности вместо группировки по смыслу (по степени логической связанности методов) — порочная практика.
Особенно если класс разбит на части (partial) в интерфейсной части публичные, а в реализации защищенные и приватные. А вот постоянное дублирование одних и тех же слов это какой-то фетиш из явы.
Для группировки по смыслу есть регионы (#region).
При реализации интерфейса мы обязаны реализовать абстрактный метод «exec» и можем опустить реализацию метода «sendNotification». Удобно?
Такое ощущение что разрабы в MS (и не только) привыкли пилить всё на интерфейсах и начисто забыли о существовании абстрактных классов.
Как заметили выше — осталось дать возможность объявлять в интерфейсе поля.
Члены интерфейса по умолчанию позволяют добавлять новые члены к интерфейсу в следующих версиях, не нарушая совместимость исходного кода с существующими реализациями этого интерфейса. Удобно.
А это тут каким боком? Не понял.
Ах, понятно. Изначально я понял утверждение наоборот, что если у интерфейса есть методы по умолчанию, то это позволяет его потом расширять.
Допустим у вас есть некий интерфейс, который реализован несколькими класами. В какой то момент вы решили немного расширить интерфейс новым членом(скажем методом). До C# 8 пришлось бы в этих классах либо реализовывать этот новый член, либо ставить заглушку, но в любом случае изменения коснулись бы всех классов реализующих этот интерфейс
ИМХО, в такой ситуации код люто напрашивается на рефакторинг(interface segregation, single responsibility)
Хочу операторы ==,<,+- у интерфейсов. Чтобы юзать синт сахар на них. Где?
interface ICommand
{
// some action
void exec();
public void build(string description)
{
Description = description;
}
public string Description { get; set; }
}
interface ICommand
{
public string Description { get; set; }
}
То в реализаторах нужно будет опять определять свойство?
Новые возможности интерфейсов в C# 8