[Ann] Next big thing in c#: default interface methods
От: Sinix  
Дата: 19.03.17 15:25
Оценка: 309 (15)
Кто там хотел трайты-миксины?
Неплохой ликбез по сабжу, тынц и тынц. Также см тут.

interface IA
{
    void M() { WriteLine("IA.M"); }
}

class C : IA { } // OK

// ...

IA i = new C();
i.M(); // prints "IA.M"


Diamond inheritance разруливается через явные вызовы:
interface IA
{
    void M() { WriteLine("IA.M"); }
}
interface IB : IA
{
    override void IA.M() { WriteLine("IB.M"); }
}
interface IC : IA
{
    override void IA.M() { WriteLine("IC.M"); }
}

class D : IA, IB, IC
{
    void IA.M() { IB.base.M(); } 
}


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

Остальные фичи с разбивкой по milestones можно глянуть тут.
Как обычно, любая может быть отменена / поменяться в любой момент времени.
Re: [Ann] Next big thing in c#: default interface methods
От: HrorH  
Дата: 20.03.17 09:49
Оценка: 58 (1) +1
Здравствуйте, Sinix, Вы писали:

S>Остальные фичи с разбивкой по milestones можно глянуть тут.


А Type Classes там видели?
И еще вот это.
Где-то там в комментах обсуждали поддержку higher kinded полиморфизма (без него многие Type Classes типа Functor, Monad и т.п. не сделать).
Но похоже без шансов, т.к. вроде требует изменения CLR.
Re[2]: [Ann] Next big thing in c#: default interface methods
От: Sinix  
Дата: 20.03.17 16:08
Оценка:
Здравствуйте, HrorH, Вы писали:

HH>А Type Classes там видели?

HH>И еще вот это.
Видел, ага. Но там война идей (в хорошем смысле) пока и до конца не понятно, куда оно пойдёт.

И https://github.com/dotnet/csharplang/issues/110 тужа же.
Re: [Ann] Next big thing in c#: default interface methods
От: Mr.Delphist  
Дата: 21.03.17 13:17
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Кто там хотел трайты-миксины?

S>Неплохой ликбез по сабжу, тынц и тынц. Также см тут.

S>
S>interface IA
S>{
S>    void M() { WriteLine("IA.M"); }
S>}


А кто-то реально сталкивался с необходимостью такого? Вот чтоб прямо надо было в реальном проекте?
Re[2]: [Ann] Next big thing in c#: default interface methods
От: TK Лес кывт.рф
Дата: 21.03.17 21:18
Оценка:
Здравствуйте, Mr.Delphist, Вы писали:

S>>
S>>interface IA
S>>{
S>>    void M() { WriteLine("IA.M"); }
S>>}


MD>А кто-то реально сталкивался с необходимостью такого? Вот чтоб прямо надо было в реальном проекте?


c java слизали. в какой-то мере развитие для extension методов плюс лучшая замена для абстрактных классов. абстрактные классы в реальных проектах же встречаются?
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[2]: [Ann] Next big thing in c#: default interface methods
От: VladD2 Российская Империя www.nemerle.org
Дата: 21.03.17 21:30
Оценка:
Здравствуйте, HrorH, Вы писали:

HH>Но похоже без шансов, т.к. вроде требует изменения CLR.


Вот этот "аргумент" уже задрал, если честно.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: [Ann] Next big thing in c#: default interface methods
От: VladD2 Российская Империя www.nemerle.org
Дата: 21.03.17 21:31
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Видел, ага. Но там война идей (в хорошем смысле) пока и до конца не понятно, куда оно пойдёт.


Все понятно как божий день. Победят недоички консерваторы, а потом... лет через 15-20 они дорастут или их сменят более грамотное люди и все сделают. Ну, мы уже на пенсии будем. Так что по фиг.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: [Ann] Next big thing in c#: default interface methods
От: VladD2 Российская Империя www.nemerle.org
Дата: 22.03.17 00:17
Оценка: +2
Здравствуйте, Mr.Delphist, Вы писали:

MD>А кто-то реально сталкивался с необходимостью такого? Вот чтоб прямо надо было в реальном проекте?


Это реально везде надо. Просто ты пока не привык мыслить подобными категориями. По сути это множественное наследование. С ним открывается совсем другой уровень декомпозиции. Можно разбить все на атомы и собирать нужные конфигурации из готовых частей.

Такой подход давно используется в С++.

Мы в Nitra
Автор: VladD2
Дата: 12.01.17
похожую штуку (множетсвенное наследование для абстрактных AST-ов) реализовали. Очень удобно!
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: [Ann] Next big thing in c#: default interface methods
От: Mr.Delphist  
Дата: 22.03.17 10:05
Оценка: -2
Здравствуйте, VladD2, Вы писали:

VD>Это реально везде надо. Просто ты пока не привык мыслить подобными категориями. По сути это множественное наследование. С ним открывается совсем другой уровень декомпозиции. Можно разбить все на атомы и собирать нужные конфигурации из готовых частей.


Синтаксический сахар, как и предполагал. На практике, всё равно это в итоге сводится к агрегированию вместо наследования, т.к. сферические атомы только в вакууме, а невакуумные атомы — хотят каких-то внешних зависимостей, и здравствуй DI.

Если они так будут продолжать, то ждём появления у интерфейсов таких вещей как конструктор, финалайзер и т.п.
Re[3]: [Ann] Next big thing in c#: default interface methods
От: Mr.Delphist  
Дата: 22.03.17 10:07
Оценка: -2
Здравствуйте, TK, Вы писали:

TK>c java слизали. в какой-то мере развитие для extension методов плюс лучшая замена для абстрактных классов. абстрактные классы в реальных проектах же встречаются?


Экономия на спичках, вот честно. Зато появился ещё один способ сделать то же самое, но несовместимо с предыдущими версиями.
Re[4]: [Ann] Next big thing in c#: default interface methods
От: VladD2 Российская Империя www.nemerle.org
Дата: 22.03.17 11:27
Оценка: +1
Здравствуйте, Mr.Delphist, Вы писали:

MD>Синтаксический сахар, как и предполагал. На практике, всё равно это в итоге сводится к агрегированию вместо наследования, т.к. сферические атомы только в вакууме, а невакуумные атомы — хотят каких-то внешних зависимостей, и здравствуй DI.


Даже не знаю как ответить на этот набор ложных утверждений и выводов из них.

Разберись в вопросе еще раз и не спеши с выводами.

Откуда ты высосал агрегирование?

Тебе в интерфейс позволяют добавлять код. При сборке окончательного класса этот код будут помещать (считай — копировать) в этот класс.

Это аналогично множественному виртуальному наследованию в С++.

Никакой агрегацией тут и не пахнет!

MD>Если они так будут продолжать, то ждём появления у интерфейсов таких вещей как конструктор, финалайзер и т.п.


Если ты так будешь поспешно выводы делать, то тебе любая супер-фича лажей будет казаться. Только проблема не в фиче, а в тебе.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: [Ann] Next big thing in c#: default interface methods
От: VladD2 Российская Империя www.nemerle.org
Дата: 22.03.17 11:37
Оценка: +1
Здравствуйте, Sinix, Вы писали:

S>Diamond inheritance разруливается через явные вызовы:


Правильный подход. Мы в Нитре такой же выбрали. Еще можно от порядка указания плясать, как в Скале. Но мне кажется это слишком ненадежно.

S>Текущее предложение предусматривает поддержку со стороны CLR и возможность добавлять новые члены в интерфейс, не ломая бинарную совместимость.


Вот здесь действительно очень тонкий момент. Дело в том, что такие методы фактически должны копироваться в окончательный класс. Такое копирование можно производить во время компиляции (как делаем мы в Нитра) и в рантайме (а так же во время ngen-а, что тоже можно считать "рантаймом", так как он происходит на машине клиент, когда все длл-и известны). Во время компиляции может получиться так, что один класс будет скомпилирован с одной версией интерфейса, а другой с другой. При этом сам интерфейс не изменится, а изменится только код этих методов. Это может привести к сложно понимаемым ошибкам.

Оптимально, чтобы такую сборку из кусочков производили JIT и ngen. Тогда во всех классах будет одна и та же версия кода.

Но для этого нужно курочить ратнайм.

S>Остальные фичи с разбивкой по milestones можно глянуть тут.

S>Как обычно, любая может быть отменена / поменяться в любой момент времени.

Боюсь, что как обычно после кучи грандиозных планов на выходе будет что-то урезанное или вообще отложат до лучших времен. А фича действительно очень полезная. Я вот в Nitra ею начал пользоваться и не нарадуюсь никак. Без нее столько копипасты или дублирования пришлось бы сделать, что становится грустно.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Отредактировано 22.03.2017 16:26 VladD2 . Предыдущая версия .
Re[2]: [Ann] Next big thing in c#: default interface methods
От: Sinix  
Дата: 22.03.17 14:51
Оценка: +1
Здравствуйте, VladD2, Вы писали:

VD>Вот здесь действительно очень тонкий момент. Дело в том, что такие методы фактически должны копироваться в окончательный класс.

VD>Оптимально, чтобы такую сборку из кусочков производили JIT и ngen. Тогда во всех классах будет одна и та же версия кода.
VD>Но для этого нужно курочить ратнайм.

Те же мысли.
Я не понял пока из обсуждений, какой из вариантов имеется в виду. Да даже если бы и понял — никаких гарантий, что в итоге сделают именно этот вариант. Короче, будем подождать.
Re[5]: [Ann] Next big thing in c#: default interface methods
От: Mr.Delphist  
Дата: 23.03.17 13:43
Оценка: :)
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, Mr.Delphist, Вы писали:


VD>Никакой агрегацией тут и не пахнет!


Ну, давайте сравним.

Новый ТРУЪ-путь:
interface IA
{
    void M() { WriteLine("IA.M"); }
}

class C : IA { } // OK

// ...

IA i = new C();
i.M(); // prints "IA.M"


Как это можно было сделать раньше (с учётом того, что множественное наследование запрещено в C#):
interface IA
{
    void M();
}

class OldGoodMixin
{
  public void M()
  {
    WriteLine("IA.M");
  }
}

class C : IA
{
  public void M()
  {
    _mixin.M();
  }
  private OldGoodMixin _mixin = new OldGoodMixin();
}
// ...

IA i = new C();
i.M(); // prints "IA.M"


Кардинальных несахарных отличий по-прежнему не вижу. Зато предвижу "радость" от того, что какой-то NuGet-пакет нельзя будет использовать в текущем проекте, потому что автор решил заюзать эту фичу, и опять надо лезть в гитхаб с напильником ради пары фиксов.

Т.е. в этом и есть проблема с моей точки зрения: добавлен ещё один способ сделать то, что можно было сделать и раньше. Если выпустят бэкпорты, как было с async/await — то нет проблем. А так, сточки зрения прикладного программиста, имеем ещё одну головную боль на ровном месте.
Отредактировано 23.03.2017 14:41 VladD2 . Предыдущая версия .
Re[6]: [Ann] Next big thing in c#: default interface methods
От: VladD2 Российская Империя www.nemerle.org
Дата: 23.03.17 15:35
Оценка:
Здравствуйте, Mr.Delphist, Вы писали:

MD>Как это можно было сделать раньше (с учётом того, что множественное наследование запрещено в C#):...


А можно еще на dynamic все залудить, соплями склеить и надеяться на на лучшее.

MD>Кардинальных несахарных отличий по-прежнему не вижу.


Ну, да. Какие отличия? Если забить на:
1. В несколько раз больший код. Ведь для каждой композиции нужно протаскивать все вызовы сквозь реагирующий объект.
2. Создание 100500 объектов вместо одного. А объект в дотнете штука не дешевая.
3. Косвенность при вызовах.
4. Необходимость делать все данные публичными или делать агрегируемые типы вложенными в агрегирующий.

То разницы нет!

MD>Зато предвижу "радость" от того, что какой-то NuGet-пакет нельзя будет использовать в текущем проекте, потому что автор решил заюзать эту фичу, и опять надо лезть в гитхаб с напильником ради пары фиксов.


Ты что-то там себе навыдумывал и пытаться этим выдумкам оппонировать.

MD>Т.е. в этом и есть проблема с моей точки зрения: добавлен ещё один способ сделать то, что можно было сделать и раньше. Если выпустят бэкпорты, как было с async/await — то нет проблем. А так, сточки зрения прикладного программиста, имеем ещё одну головную боль на ровном месте.


Нет никаких других способов. Сейчас есть только один способ — надолбить тучу кода. Наличие такой фичи радикально меняет дизайн программ. Ты получаешь возможность создавать типы путем композиции их из мелких заготовок не тратя время на написание оберток и память на агрегацию.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: [Ann] Next big thing in c#: default interface methods
От: Mr.Delphist  
Дата: 23.03.17 16:44
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Ну, да. Какие отличия? Если забить на:

VD>1. В несколько раз больший код. Ведь для каждой композиции нужно протаскивать все вызовы сквозь реагирующий объект.
Если интерфейсный метод из одной строки — да, код хелло-ворлда удвоится. Если же это что-то реальное из боевого проекта — разница в несколько строк роли не сыграет.

VD>2. Создание 100500 объектов вместо одного. А объект в дотнете штука не дешевая.

LINQ с генериками просили передать тёплый привет

VD>3. Косвенность при вызовах.

На эту тему столько копий сломано ещё с ASM-времён, что ой.

VD>4. Необходимость делать все данные публичными или делать агрегируемые типы вложенными в агрегирующий.

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

IA i = new C();
i.M(); // prints "IA.M"

C c = new C();
c.M(); // prints "IA.M"
Re[6]: [Ann] Next big thing in c#: default interface methods
От: Sinclair Россия https://github.com/evilguest/
Дата: 23.03.17 16:58
Оценка:
Здравствуйте, Mr.Delphist, Вы писали:

MD>Здравствуйте, VladD2, Вы писали:


VD>>Здравствуйте, Mr.Delphist, Вы писали:


VD>>Никакой агрегацией тут и не пахнет!


MD>Ну, давайте сравним.


Не, давайте по-настоящему.
public interface IOut
{
   void PrintChar(char c);
   void PrintString(string chars)
   {
     foreach(var c in chars)
       PrintChar(c);
   }
}

public class C: IOut
{
  public void PrintChar(char c)
  {
    System.Console.Write(c);
  }
}

Как это можно было сделать раньше (с учётом того, что множественное наследование запрещено в C#):

interface IA
{
   void PrintChar(char c);
   void PrintString(string chars)
}

class OldGoodMixin
{
  public OldGoodMixin(IOut o)
  {
    _o = o;
  }
  private IOut _o;

  public void PrintString(string chars)
  {
     foreach(var c in chars)
       _o.PrintChar(c);
  }
}

class C : IA
{
  public void PrintChar(char c)
  {
    System.Console.Write(c);
  }
  public void PrintString(string s)
  {
    _mixin.PrintString(s);
  }

  private OldGoodMixin _mixin;
  public C()
  {
     _mixin = new OldGoodMixin();
  }
}

Вопросы есть?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[7]: [Ann] Next big thing in c#: default interface methods
От: AlexRK  
Дата: 23.03.17 17:14
Оценка: +2
Здравствуйте, Sinclair, Вы писали:

S>Не, давайте по-настоящему.

S>
S>public interface IOut
S>{
S>   void PrintChar(char c);
S>   void PrintString(string chars)
S>   {
S>     foreach(var c in chars)
S>       PrintChar(c);
S>   }
S>}

S>public class C: IOut
S>{
S>  public void PrintChar(char c)
S>  {
S>    System.Console.Write(c);
S>  }
S>}
S>

S>Как это можно было сделать раньше (с учётом того, что множественное наследование запрещено в C#):

public interface IOut
{
   void PrintChar(char c);
}

static class OldGoodMixin
{
  public static void PrintString(this IOut o, string chars)
  {
     foreach(var c in chars)
       o.PrintChar(c);
  }
}

public class C: IOut
{
  public void PrintChar(char c)
  {
    System.Console.Write(c);
  }
}
Re[8]: [Ann] Next big thing in c#: default interface methods
От: TK Лес кывт.рф
Дата: 23.03.17 19:39
Оценка:
Здравствуйте, AlexRK, Вы писали:

Теперь простое задание: надо добавить в интерфейс IOut новый метод PrintString2. Класс B должен содержать собственную реализацию PrintString2.
Класс C — Legacy и его трогать нельзя.

IOut out1 = new C();
IOut out2 = new B();

out1.PrintString2(); // Default PrintString2
out2.PrintString2(); // Updated PrintString2
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[9]: [Ann] Next big thing in c#: default interface methods
От: AlexRK  
Дата: 23.03.17 19:44
Оценка:
Здравствуйте, TK, Вы писали:

TK>Теперь простое задание: надо добавить в интерфейс IOut новый метод PrintString2. Класс B должен содержать собственную реализацию PrintString2.

TK>Класс C — Legacy и его трогать нельзя.

TK>
TK>IOut out1 = new C();
TK>IOut out2 = new B();

TK>out1.PrintString2(); // Default PrintString2
TK>out2.PrintString2(); // Updated PrintString2
TK>


static class OldGoodMixin
{
  public static void PrintString2(this IOut o)
  {
     // ...
  }
}

public class B: IOut
{
  public void PrintString2()
  {
     // ...
  }
}
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.