[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()
  {
     // ...
  }
}
Re[9]: [Ann] Next big thing in c#: default interface methods
От: hardcase Пират http://nemerle.org
Дата: 23.03.17 19:56
Оценка: +2
Здравствуйте, TK, Вы писали:

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


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

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

Так если его нельзя трогать, как может речь идти о добавлении нового метода? Значит будет новый интерфейс, который класс C поддерживать не будет.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[10]: [Ann] Next big thing in c#: default interface methods
От: TK Лес кывт.рф
Дата: 23.03.17 20:10
Оценка:
Здравствуйте, AlexRK, Вы писали:

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>>


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

ARK>public class B: IOut
ARK>{
ARK>  public void PrintString2()
ARK>  {
ARK>     // ...
ARK>  }
ARK>}
ARK>


Запускать будем? Ключевой момент я жирным выделил
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[10]: [Ann] Next big thing in c#: default interface methods
От: TK Лес кывт.рф
Дата: 23.03.17 20:11
Оценка:
Здравствуйте, hardcase, Вы писали:

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

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

H>Так если его нельзя трогать, как может речь идти о добавлении нового метода? Значит будет новый интерфейс, который класс C поддерживать не будет.


Так в этом то и смысл: пишете тут — добавляется там
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[11]: [Ann] Next big thing in c#: default interface methods
От: AlexRK  
Дата: 23.03.17 20:24
Оценка: :)))
Здравствуйте, TK, Вы писали:

TK>Запускать будем? Ключевой момент я жирным выделил


А, не заметил. Ну пожалуйста:

static class OldGoodMixin
{
  public static void PrintString2(this IOut o)
  {
    if (o is B)
    {
     // ...
    }
    else
    {
     // ...
    }
  }
}


Re[11]: [Ann] Next big thing in c#: default interface methods
От: hardcase Пират http://nemerle.org
Дата: 23.03.17 20:39
Оценка: +1
Здравствуйте, TK, Вы писали:

TK>Так в этом то и смысл: пишете тут — добавляется там


Я так понял исходники C доступны, только не понятно, почему их менять не нельзя, а код интерфейса — можно.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[12]: [Ann] Next big thing in c#: default interface methods
От: TK Лес кывт.рф
Дата: 23.03.17 21:11
Оценка:
Здравствуйте, hardcase, Вы писали:

TK>>Так в этом то и смысл: пишете тут — добавляется там

H>Я так понял исходники C доступны, только не понятно, почему их менять не нельзя, а код интерфейса — можно.

Посмотрите как это в java было — просто в какой-то момент расширили базовые библиотечные интерфейсы при этом не поломав существующий код.
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[8]: [Ann] Next big thing in c#: default interface methods
От: Sinclair Россия https://github.com/evilguest/
Дата: 24.03.17 04:12
Оценка: +2
Здравствуйте, AlexRK, Вы писали:

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

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

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

Да, верно. Extension методы — мегакруто. Но есть и нюансы:

public class C: IOut
{
   public void PrintChar(char c)
   {
      using(w = StreamWriter.OpenWrite("out.txt", true))
       w.Write(c);
   }
   public void PrintString(string chars)
   {
      using(w = StreamWriter.OpenWrite("out.txt", true))
       w.Write(chars);
   }
}

public static class D
{
   public static void Test()
   {
     var c = new C();
     TestClass(c);
     TestIntf(c);
   } 
   public static void TestClass(C output)
   {
     output.PrintString("Hello, world!"); 
   }
   public static void TestIntf(IOut output)
   {
     output.PrintString("Hello, world!"); // упс - мы вызываем дефолтную неэффективную реализацию вместо оптимизированной удобной.
   }
}
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re: [Ann] Next big thing in c#: default interface methods
От: Doc Россия http://andrey.moveax.ru
Дата: 24.03.17 05:25
Оценка: +3
Здравствуйте, Sinix, Вы писали:

Блин. Вот чего меньше всего хотелось это увидеть код имплементации в интерфейсе.
Зачем мешать контракт и реализацию? Печаль
Re[2]: [Ann] Next big thing in c#: default interface methods
От: Sinclair Россия https://github.com/evilguest/
Дата: 24.03.17 08:07
Оценка: +1
Здравствуйте, Doc, Вы писали:
Doc>Зачем мешать контракт и реализацию? Печаль
Затем, что мир не делится на чёрное и белое, или "контракт vs реализация".
Например, IEnumerable.Count — это контракт или реализация?
С одной стороны, неохота включать Count в контракт IEnumerable, потому что это обяжет всех подряд заниматься его написанием.
С другой стороны, без него неудобно.
С третьей стороны, в 95% случаев нас устроит дефолтная реализация, выраженная через пересчёт результатов GetEnumerator.
С четвёртой стороны, в 5% случаев она нас не устраивает по соображениям производительности, и мы хотим иметь возможность реализовать её эффективнее.
В итоге, без концепции "дефолтной реализации" у нас одно из трёх:
1. Каждый клиент по месту припиливает foreach(var i in e) count++
2. 19 из 20 реализаторов IEnumerable вынужден выписывать foreach(var i in this) count++; и только один пишет там что-то более умное (например, this._count;)
3. Реализация Enumerable.Count развлекается игрой в угадайку типа if (arg is IList) { return (IList(arg)).Count;}

В итоге, у нас получается куча вот таких вот "утилитных методов", которые занимают промежуточное положение — клиент требует, чтобы они были, а вот сервер не должен быть обязан их предоставлять.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re: [Ann] Next big thing in c#: default interface methods
От: yenik  
Дата: 24.03.17 09:12
Оценка: 6 (2) :)))
Мда, вопрос "Чем интерфейс отличается от абстрактного класса?" становится не столь безобидным.
Re[3]: [Ann] Next big thing in c#: default interface methods
От: HrorH  
Дата: 24.03.17 10:04
Оценка:
Здравствуйте, Sinclair, Вы писали:

Если кто-то хочет дефолтную реализацию, сделали бы для них ключевое слово trait.
А для тех кто не хочет мешать контракт и реализацию, оставили бы в языке хотя бы одно ключевое слово, которое позволяет задать чистый контракт.
Re[3]: [Ann] Next big thing in c#: default interface methods
От: Doc Россия http://andrey.moveax.ru
Дата: 24.03.17 10:20
Оценка: +3 :))
Здравствуйте, Sinclair, Вы писали:

Doc>>Зачем мешать контракт и реализацию? Печаль

S>Затем, что мир не делится на чёрное и белое, или "контракт vs реализация".

Вот ровно с такой же мотивацией можно смешать все что угодно.
А по факту — контракт это абстракция, реализация ... ну тут само слово говорит за себя.

Изначально интерфейсы отделили от реализации ради абстракции и вот сейчас просто решили пойти на наперекор самой идеи интерфейсов.

S>Например, IEnumerable.Count — это контракт или реализация?


Вопрос не корректный, т.к. мы все знаем что это extension метод. Но он не является частью контракта интерфейсов с которыми работает.
По сути это имплементация, которая полагается на контракт IEnumerable.

S>В итоге, у нас получается куча вот таких вот "утилитных методов", которые занимают промежуточное положение — клиент требует, чтобы они были, а вот сервер не должен быть обязан их предоставлять.


И для его есть вполне удобные extension методы, которые решают как раз вопрос вот таких Count.
Нужны дефолтные методы? Есть abstract class.
Зачем при этом смешивать абстракции и реализации — не ясно.
Re[4]: [Ann] Next big thing in c#: default interface methods
От: Sinix  
Дата: 24.03.17 14:57
Оценка:
Здравствуйте, HrorH, Вы писали:

HH>Если кто-то хочет дефолтную реализацию, сделали бы для них ключевое слово trait.

Тут проблема в том, что в CLS нет трайтов.

Т.е. или под трайтами прятать те же интерфейсы (и для клиентов библиотеки они будут выглядеть как интерфейсы, помеченные служебным атритутом), или получаем просто синтаксический сахар, без бинарной совместимости.
Re[9]: [Ann] Next big thing in c#: default interface methods
От: AlexRK  
Дата: 25.03.17 06:54
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Да, верно. Extension методы — мегакруто. Но есть и нюансы:


Кстати, пришло в голову — так надо было бы сделать динамическую диспетчеризацию для методов расширения, т.е. выбор extension-метода по реальному типу параметра this, а не статическому. Вроде особых подводных камней тут не должно быть.
Re[4]: [Ann] Next big thing in c#: default interface methods
От: Sinclair Россия https://github.com/evilguest/
Дата: 25.03.17 09:27
Оценка:
Здравствуйте, HrorH, Вы писали:

HH>Если кто-то хочет дефолтную реализацию, сделали бы для них ключевое слово trait.

И сломали бы неизвестное количество проектов, где есть переменные и мемберы с именем trait?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[5]: [Ann] Next big thing in c#: default interface methods
От: HrorH  
Дата: 25.03.17 14:55
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>И сломали бы неизвестное количество проектов, где есть переменные и мемберы с именем trait?

А почему компилятор не может отличить название переменной от ключевого слова, как это он делает например с async?
Re[3]: [Ann] Next big thing in c#: default interface methods
От: Silver_S Ниоткуда  
Дата: 25.03.17 21:36
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>... Можно разбить все на атомы и собирать нужные конфигурации из готовых частей.

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

Собирать из кусочков хорошо, только вот бы еще одну фичу из С++ — private наследование интерфейсов. Почему не предлагают, не уж то это только мне требуется?
Уже не мало классов пришлось написать, которым в конструктор передается по 3-4 делегата, кроме прочего.
Можно было бы один интерфейс передать. Но как его реализовывать в классе-клиенте этой штуки, если используется приватно, и нельзя поганить класс-клиент публичным наследованием?
Альтернатива только в классе-клиенте private nested класс делать, в нем интерфейс реализуется, методы интерфейса вызывают поля-делегаты, эти поля заполняются классом-клиентом. Хотя бы так сделали без изменения CLR.
Отредактировано 25.03.2017 21:42 Silver_S . Предыдущая версия .
Re[4]: [Ann] Next big thing in c#: default interface methods
От: Mystic Artifact  
Дата: 25.03.17 22:00
Оценка:
Здравствуйте, Silver_S, Вы писали:

private интерфейс смысла не имеет как интерфейс (но имеет как контракт — т.е. выдаем публичные методы без публикации интерфейса). Но это не так как работает C#. Короче — конечно же ты не один. Самый лучший — C++ наверное, но вообще нужно ещё больше. Нужны user defined access tokens/scopes (времени компиляции), для доступа к членам. Но это абсолютно зависит от задач. Кому-то это покажется бредом. Да, кстати — кому показалось — идите, не задерживайтесь.
Re[4]: [Ann] Next big thing in c#: default interface methods
От: VladD2 Российская Империя www.nemerle.org
Дата: 26.03.17 00:58
Оценка:
Здравствуйте, Silver_S, Вы писали:

S_S>Собирать из кусочков хорошо, только вот бы еще одну фичу из С++ — private наследование интерфейсов. Почему не предлагают, не уж то это только мне требуется?


Похоже — да. Я даже когда писал на плюсах его не использовал. Это даже звучит как оксюморон. Интерфейс подразумевает публичность, а тут вдруг приватное его наследование. Это или не наследование, или не интерфейс.

S_S>Уже не мало классов пришлось написать, которым в конструктор передается по 3-4 делегата, кроме прочего.

S_S>Можно было бы один интерфейс передать. Но как его реализовывать в классе-клиенте этой штуки, если используется приватно, и нельзя поганить класс-клиент публичным наследованием?

Делегаты ты в поля кладешь и ничего вроде. Чем интерфейс отличается в данном случае?

S_S>Альтернатива только в классе-клиенте private nested класс делать, в нем интерфейс реализуется, методы интерфейса вызывают поля-делегаты, эти поля заполняются классом-клиентом. Хотя бы так сделали без изменения CLR.


Что-то все очень сложно. Можно просто реализовывать интерфейс или базовый класс во вложенном приватном классе. Все детали останутся в нем, а возвращен будет публичный интерфейс. Возможно я не очень понимаю решаемой задачи.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: [Ann] Next big thing in c#: default interface methods
От: Silver_S Ниоткуда  
Дата: 26.03.17 11:31
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Делегаты ты в поля кладешь и ничего вроде. Чем интерфейс отличается в данном случае?

Только тем что не так громоздко выглядит, как если: 4 делегата передавать в конструктор. Для этих делегатов имена параметров задать нельзя (иногда это очень плохо) голые Func, хорошо если делегаты без ref,out. Либо явно объявлять 4 delegate. Еще и 4 поля и 4 присвоения.
Ну лучше бы выглядел код, с interface, когда так много делегатов передается.

S_S>>Альтернатива только в классе-клиенте private nested класс делать, в нем интерфейс реализуется,

VD>Что-то все очень сложно. Можно просто реализовывать интерфейс или базовый класс во вложенном приватном классе. Все детали останутся в нем, а возвращен будет публичный интерфейс. Возможно я не очень понимаю решаемой задачи.
Я об этом и говорю — во вложенном приватном классе, и в этот вложенный приватный класс передавать ссылку на родительский класс. Компактнее бы это все выглядело как private наследование.
Смысл в том что наружу этот интерфейс не показывается, он передается только агрегированным приватным объектам.

Такое имеется ввиду ( в конструктор Some надо передавать IInterface1):
    class Parent
    {
        private class Interface1Impl : IInterface1
        {
            public Interface1Impl(Parent p)
            {
                _p = p;
            }
            Parent _p; //Для реализации интерфейса нужен доступ в Parent
        }
        public Parent()
        {
            _interface1Impl=new Interface1Impl(this);
            _some = new Some(_interface1Impl);
        }
        private Some _some;
        private Interface1Impl _interface1Impl;
    }

Было бы private наследование, никому бы не мешало, когда не надо. А здесь бы можно было так:
    class Parent: private IInterface1
    {        
        public Parent()
        {
            _some = new Some(this);
        }
        private Some _some;
    }


Зачем вынесен Some из Parent это другой вопрос — этот Some используется в нескольких Parent, и к тому же должен быть в другой более абстрактной сборке.
Отредактировано 26.03.2017 11:46 Silver_S . Предыдущая версия . Еще …
Отредактировано 26.03.2017 11:36 Silver_S . Предыдущая версия .
Re: [Ann] Next big thing in c#: default interface methods
От: vorona  
Дата: 26.03.17 15:32
Оценка: 34 (3) +1
The C# Programming Language

Krzysztof Cwalina

Perhaps I am stirring up quite a bit of controversy with this statement, but I believe the lack of support for multiple inheritance in our type system is the single biggest contributor to the complexity of the .NET Framework. When we designed the type system, we explicitly decided not to add support for multiple inheritance so as to provide simplicity. In retrospect, this decision had the exact opposite effect. The lack of multiple inheritance forced us to add the concept of interfaces, which in turn are responsible for problems with the evolution of the framework, deeper inheritance hierarchies, and many other problems.

Re[6]: [Ann] Next big thing in c#: default interface methods
От: Sinclair Россия https://github.com/evilguest/
Дата: 27.03.17 09:13
Оценка:
Здравствуйте, HrorH, Вы писали:
HH>А почему компилятор не может отличить название переменной от ключевого слова, как это он делает например с async?
Потому что async в качестве ключевого слова встречается только там, где не может стоять никакая переменная или имя типа.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[10]: [Ann] Next big thing in c#: default interface methods
От: Sinclair Россия https://github.com/evilguest/
Дата: 27.03.17 10:23
Оценка:
Здравствуйте, AlexRK, Вы писали:
ARK>Кстати, пришло в голову — так надо было бы сделать динамическую диспетчеризацию для методов расширения, т.е. выбор extension-метода по реальному типу параметра this, а не статическому. Вроде особых подводных камней тут не должно быть.
Навскидку, это открывает потенциальную дверь в бесконечность. Поведение кода может произвольно измениться просто из-за того, что в домен загрузили новую сборку с более подходящим extension.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[7]: [Ann] Next big thing in c#: default interface methods
От: HrorH  
Дата: 27.03.17 11:58
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Потому что async в качестве ключевого слова встречается только там, где не может стоять никакая переменная или имя типа.

Так вроде бы и с trait также

   public trait Foo
   {
     ...
   }


какая тут может стоять переменная или имя типа, чего-то не могу въехать.
Re[2]: [Ann] Next big thing in c#: default interface methods
От: yenik  
Дата: 27.03.17 13:34
Оценка: +3
V>The C# Programming Language

V>Krzysztof Cwalina

V>

V>Perhaps I am stirring up quite a bit of controversy with this statement, but I believe the lack of support for multiple inheritance in our type system is the single biggest contributor to the complexity of the .NET Framework. When we designed the type system, we explicitly decided not to add support for multiple inheritance so as to provide simplicity. In retrospect, this decision had the exact opposite effect. The lack of multiple inheritance forced us to add the concept of interfaces, which in turn are responsible for problems with the evolution of the framework, deeper inheritance hierarchies, and many other problems.


Сильно. Только если бы они с самого начала решили по-другому, неизвестно, оказался бы хрен слаще редьки.
Re[8]: [Ann] Next big thing in c#: default interface methods
От: Sinclair Россия https://github.com/evilguest/
Дата: 27.03.17 16:34
Оценка:
Здравствуйте, HrorH, Вы писали:

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


S>>Потому что async в качестве ключевого слова встречается только там, где не может стоять никакая переменная или имя типа.

HH>Так вроде бы и с trait также

HH>
HH>   public trait Foo
HH>   {
HH>     ...
HH>   }
HH>


HH>какая тут может стоять переменная или имя типа, чего-то не могу въехать.

В текущем C# это компилируется Ок:
public class Test
{
    public class trait { }
    public trait IFoo { get; set;}
}

Попробуйте заставить это скомпилироваться в вашем гипотетическом C# с ключевым словом trait.
Прямолинейная реализация приведёт к поведению, такому же как сейчас для
public class Test
{
    public class interface { }
    public interface IFoo { get; set;}
}
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[9]: [Ann] Next big thing in c#: default interface methods
От: HrorH  
Дата: 27.03.17 21:17
Оценка: :)
Здравствуйте, Sinclair, Вы писали:

S>Попробуйте заставить это скомпилироваться в вашем гипотетическом C# с ключевым словом trait.

Если проблема только с вложенными trait, то их можно просто запретить.
Тем более что непонятно, какая от них польза. По крайней мере вложенных интерфейсов я чего-то видел немного.
Re: [Ann] Next big thing in c#: default interface methods
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 04.04.17 08:28
Оценка:
Здравствуйте, Sinix, Вы писали:

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

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

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

S>class C : IA { } // OK

S>// ...

 Есть в Delphi есть директива implements 

[q]
Случается, что реализация интерфейса содержится во вложенном объекте класса. Тогда не требуется программировать реализацию интерфейса путем замыкания каждого метода интерфеса на соответствующий метод вложенного объекта. Достаточно делегировать реализацию интерфейса вложенному объекту с помощью директивы implements:
[/q]
type
 
[pascal]
 TTextParser = class(TInterfacedObject, ITextReader)
    ...
    FTextReader: ITextReader;
    property TextReader: ITextReader read FTextReader implements ITextReader;
    ...
  end;

[/pascal]
[cs]
В этом примере интерфейс ITextReader в классе TTextParser реализуется не самим классом, а его внутренней переменной FTextReader.

Очевидно, что внутренний объект должен быть совместим с реализуемым интерфейсом.



Вот это было бы интересно и ближе к множественному наследованию.

При этом можно делать автоматические обертки по образу и подобиb fody PropertyChanged

https://github.com/Fody/PropertyChanged
и солнце б утром не вставало, когда бы не было меня
Re[4]: [Ann] Next big thing in c#: default interface methods
От: VladiCh  
Дата: 06.04.17 01:32
Оценка:
Здравствуйте, Silver_S, Вы писали:

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


S_S>Собирать из кусочков хорошо, только вот бы еще одну фичу из С++ — private наследование интерфейсов. Почему не предлагают, не уж то это только мне требуется?

S_S>Уже не мало классов пришлось написать, которым в конструктор передается по 3-4 делегата, кроме прочего.
S_S>Можно было бы один интерфейс передать. Но как его реализовывать в классе-клиенте этой штуки, если используется приватно, и нельзя поганить класс-клиент публичным наследованием?
S_S>Альтернатива только в классе-клиенте private nested класс делать, в нем интерфейс реализуется, методы интерфейса вызывают поля-делегаты, эти поля заполняются классом-клиентом. Хотя бы так сделали без изменения CLR.

Это с самых первых версий есть в VB.NET. Можно просто использовать вместо C# где необходимо .
Re[5]: [Ann] Next big thing in c#: default interface methods
От: AngeL B. Россия  
Дата: 07.04.17 09:04
Оценка: +1
Здравствуйте, Sinclair, Вы писали:

HH>>Если кто-то хочет дефолтную реализацию, сделали бы для них ключевое слово trait.

S>И сломали бы неизвестное количество проектов, где есть переменные и мемберы с именем trait?

Вот самая из натянутых отговорок, честно.
С современными средами разработки и методами рефакторинга это наименьшая из проблем.
Могли бы ключ компилятора в конце концов сделать какой или еще чего.
Re[6]: [Ann] Next big thing in c#: default interface methods
От: Sinclair Россия https://github.com/evilguest/
Дата: 07.04.17 11:16
Оценка: +1
Здравствуйте, AngeL B., Вы писали:

AB>Вот самая из натянутых отговорок, честно.

Это вам кажется.
AB>С современными средами разработки и методами рефакторинга это наименьшая из проблем.
И это вам кажется. Далеко не всегда есть возможность поправить исходник.
AB>Могли бы ключ компилятора в конце концов сделать какой или еще чего.
А это — вообще тупик. С тем же успехом можно просто не выпускать фичу. Стоимость тестирования возрастает на ровном месте вдвое: ведь нам надо проверить, что все тесты работают корректно с обоими ключами компилятора.
При этом те, кому нужен ключ, по факту не применяют новую фичу совсем — т.е. ездят на старой версии компилятора.
Ведь в шарпе нет частичной компиляции — то есть если у нас "сломан" один файл в проекте, то отключить фичу придётся во всём проекте.
Вы бы почитали блоги Липперта, что ли. Он там очень много вещей подробно обсуждает с точки зрения команды компилятора.

Очень легко принимать такие решения, когда у твоего продукта полтора человека пользователей, или ты опенсорсник, которому наплевать на свою аудиторию, и никаких обязательств у тебя перед ними нет.
А когда ты работаешь в коммерческой компании, то backwards compatibility становится ночным кошмаром.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[7]: [Ann] Next big thing in c#: default interface methods
От: Max Mustermann  
Дата: 07.04.17 13:07
Оценка:
Здравствуйте, Sinclair, Вы писали:

AB>>Вот самая из натянутых отговорок, честно.

S>Это вам кажется.

Ок, мне тоже "кажется".
Раскройте еще раз эти же тезисы применительно к yeld, var, await, dynamic, from, foreach...
Re[7]: [Ann] Next big thing in c#: default interface methods
От: artelk  
Дата: 07.04.17 13:22
Оценка: +1
Здравствуйте, Sinclair, Вы писали:

S>Очень легко принимать такие решения, когда у твоего продукта полтора человека пользователей, или ты опенсорсник, которому наплевать на свою аудиторию, и никаких обязательств у тебя перед ними нет.

S>А когда ты работаешь в коммерческой компании, то backwards compatibility становится ночным кошмаром.

https://msdn.microsoft.com/en-us/library/hh678682(v=vs.110).aspx
Вот тут список ломающих изменений, которые, имхо, с большей вероятностью ломают обратную совместимость случайного кода в вакууме. И ничего, включили их.
Re[9]: [Ann] Next big thing in c#: default interface methods
От: artelk  
Дата: 07.04.17 13:31
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>В текущем C# это компилируется Ок:

S>
S>public class Test
S>{
S>    public class trait { }
S>    public trait IFoo { get; set;}
S>}
S>

S>Попробуйте заставить это скомпилироваться в вашем гипотетическом C# с ключевым словом trait.

class var{
  public static implicit var(int n){...}
}
//...

var x = 42;

так же и поступать — если в области видимости есть такой тип — считать, что имеется ввиду он.
Re[2]: [Ann] Next big thing in c#: default interface methods
От: artelk  
Дата: 07.04.17 14:49
Оценка:
Здравствуйте, Doc, Вы писали:

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


Doc>Блин. Вот чего меньше всего хотелось это увидеть код имплементации в интерфейсе.

Doc>Зачем мешать контракт и реализацию? Печаль

Контракт это не обязательно только безликие сигнатуры. В него так же могут быть включены некоторые дополнительные утверждения, нарушив которые ты нарушаешь LSP.
Поэтому народ придумывает всякие code contracts и т.п. Часть таких утверждений можно закодировать в виде дефолтных реализаций или методах расширения.
Например, утверждение, что для чисел выполняется x-y==x+(-y), поэтому бинарный минус можно реализовать через унарный и операцию сложения.
Но если его сделать методом расширения, ты теряешь возможность реализовать его более эффективным способом для BigInteger.
Или вот:
interface IEnumerable<T>
{
  //...
  bool Contains(T value)
  {
    foreach(var item in this)
    {
      if(item == value)
        return true;
    }

    return false;
  }
}

class HashSet<T>: IEnumerable<T>, ISet<T>
{
  bool Contains(T value)
  {
    //более эффективная реализация, но с тем же результатом
  }
}

void Do(IEnumerable<T> items)
{
  b = items.Contains(...);
  //вместо такого:
  if(items is ISet<T>)
    b = (ISet<T>)items.Contains(...);
  else if(items is SomethingElseThatIsSupposedToHaveEffectiveContains<T>)
    b = ...
}



https://github.com/dotnet/corefx/blob/master/src/System.Linq/src/System/Linq/First.cs
https://github.com/dotnet/corefx/blob/master/src/System.Linq/src/System/Linq/Count.cs
https://github.com/dotnet/corefx/blob/master/src/System.Linq/src/System/Linq/Skip.cs
...
Кучу извращий можно было бы избежать.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.