Войти
ФлеймФорумПрограммирование

Интерфейсы в C# 8.0 (4 стр)

Страницы: 1 2 3 4 5 6 7 Следующая »
#45
(Правка: 16:45) 16:44, 4 сен. 2019

skalogryz
> как это "понапишешь в класс"? в классы ты можешь добавить методов, но если ты с
> объектом работаешь только через интерфейс (и никогда к напрямую к методам
> класса), то не взлетит - ты же эти методы не "увидишь". Тебе нужно будет новый
> интерфейс добавлять.
>
>
Ты чтото с темы на тему прыгаешь. Речь идет о том зачем вообще в интерфейс добавили имплементацию по дефолту. И я тебе отвечаю, что эту имплементацию по дефолту можно добавлять куда хочешь. Конректно так:

interface A {

void MyA();
void MyB();

}

class DefaultA
{
public static void MyA(){};
}

class ImplementationA : A
{
public void MyA() => DefaultA.MyA();

}

От строчки public void MyA() => DefaultA.MyA();  руки не отвалятся. А инлайнингом должен заниматься компилятор.


#46
16:52, 4 сен. 2019

slepov
> руки не отвалятся
сначала надо найти как этот DefaultA называется в конкретной библиотеке, потом посмотреть список методов для которых это требуется, ну и потом написать по

public static System.Linq.ParallelQuery AsParallel (this System.Collections.IEnumerable source) => System.Collections.IEnumerableDefault.AsParallel(this);
для каждого такого метода. И главное зачем? Кому эта дефолтная реализация навредила?
#47
(Правка: 16:58) 16:56, 4 сен. 2019

slepov
> От строчки public void MyA() => DefaultA.MyA();  руки не отвалятся. А
> инлайнингом должен заниматься компилятор.
как это не отвалятся? у тебя был ImplementationA, который реализовывал

interface A {
void MyA();
}
потом решили что MyA() мало, и добавили
interface A {
  void MyA();
  void MyB();
}

на данный момент, компиляция класса implementationA невозможна, потому что MyB() не реализован.
Ты можешь написать

class ImplementationA : A
{
public void MyB() => DefaultB.MyB();
}
но в том случае если у тебя 100500 классов, то руки (и дедлайны) могут серьёзно пострадать.

Ты можешь сказать, что ты контроллируешь "Interface A", и такие изменения, ты можешь предугадать и сделать 100500 изменений.
А если не ТЫ контролируешь "Interface A", а майкрософт, или ещё какой вендор.
То ему будет намного спокойнее, если их следующие изменения не поломают твой проект.

#48
17:00, 4 сен. 2019

skalogryz
> потом решили что MyA() мало, и добавили

В третий раз тебе говорю: не путай тему дефолтовой имплементации с темой изменения контракта. Темы  разные.

#49
17:04, 4 сен. 2019

kipar
> Кому эта дефолтная реализация навредила?

Мне и топик стартеру. Наверняка мы неодиноки. Есть и еще проблема. Представь что эту дефолтовую реализацию ктото захочет вызвать между строчек своей. И как это делать? Полагаю какой то новый спецсинтаксис? Ну и нахрена это надо? Из контрактов снова сделали множественное наследование абстрактных классов. Круто че.. А если дефолтовая имплементация требует состояние? То еще и поля понафигачить можно в интерфейс так чтоли? Получается контракты превращаются в какое то месиво фич. Мне лично грустно.

#50
(Правка: 17:08) 17:05, 4 сен. 2019

slepov
> В третий раз тебе говорю: не путай тему дефолтовой имплементации с темой
> изменения контракта. Темы разные.
так я и говорю, что изменение контракта это плохо.
но иногда людям это очень хочеться сделать, и при этом не огрести.
по-этому изменения в контракте невелируют, наличием дефолтовой имплементации.

slepov
> Мне лично грустно.
и в этом соль. Что ты в своих проектах (и своих интерфейсах), можешь запретить использование этой фичи.
А злостные M$ будут пополянть "стандартные интерфейсы" новыми методами, и тебе не вредить.

slepov
> А если дефолтовая имплементация требует состояние? То еще и поля понафигачить можно в интерфейс так чтоли?
поля в интерфейс нельзя (можно свойства, но не поля)
так что состояния она не будет требовать.

#51
17:12, 4 сен. 2019

skalogryz
> А злостные M$ будут пополянть "стандартные интерфейсы" новыми методами, и тебе
> не вредить.

Слабо утешил. Я как то привык что если декларирован интерфейс то за ним стоит _только_ контракт. Сейчас будет "не, мы еще понафигачили имплементацию". Причем это придется же как то отображать в том же Object Browser, доках. И какую проблему они этим решили? Ах да.. сейчас будет банальное " в том случае если у тебя 100500 классов".

> поля в интерфейс нельзя (можно свойства, но не поля)
> так что состояния она не будет требовать.

Ну т.е. можно писать недоимплементации ). Ну это в духе MS. Латая какие то дыры платформы они увечат сам язык.

#52
17:15, 4 сен. 2019

skalogryz
У вендора есть класс Notifier, который шлёт подписчикам некоторые уведомления. Нужно лишь подписчикам реализовать интерфейс IListener и подписаться. Вот этот интерфейс:

interface IListener
{
    void Notify(string message);
}
Я реализую этот интерфейс в своём классе:
class MyListener : IListener
{
    void Notify(string message)
    {
        Console.WriteLine(message);
    }
}
затем подписываюсь на измещения:
Notifier notifier;
// ...
IListener listener = new MyListener();
notifier.Subscribe(listener);
Всё отлично. Вендор делает рассылку уведомлений, всем подписчикам. Все рады, я рад.
Но ситуация меняется и вендору нужно ещё рассылать предупреждения. И он решает не создавать вторую версию API для этого дела, а добавить в существующий интерфейс новый метод:
interface IListener
{
    void Notify(string message);
    void Warning(string message, int warningLevel);
}
...стоп, но так сломается код у всех, кто использовал интерфейс IListener без метода Warning!

И тут на сцену выходит skalogryz и применяет дефолтную реализацию методов!!!111

Покажи, как ты поступишь в этой ситуации.

#53
17:21, 4 сен. 2019

slepov
> Ну и нахрена это надо?
> Получается контракты превращаются в какое то месиво фич. Мне лично грустно.
а, ну это нормально, я думал какие-то по существу возражения есть. Так-то про любой сахар можно сказать "месиво фич, рука не отвалится без него написать".

#54
(Правка: 17:28) 17:28, 4 сен. 2019

Нихао
> И тут на сцену выходит skalogryz и применяет дефолтную реализацию методов!!!111
> Покажи, как ты поступишь в этой ситуации.

    void Warning(string message, int warningLevel) => Notify(message);
#55
17:29, 4 сен. 2019

skalogryz
> void Warning(string message, int warningLevel) => Notify(message);
Это чтобы посетителям метрополитена кроме сообщений о прибытии поездов ещё прилетали сообщения о том, кто попал под колёса и куда укатилась его голова?

#56
17:32, 4 сен. 2019

Нихао
> Это чтобы посетителям метрополитена кроме сообщений о прибытии поездов ещё
> прилетали сообщения о том, кто попал под колёса и куда укатилась его голова?
почему нет?!

#57
17:32, 4 сен. 2019

  Кто бы только мог подумать, что у кого-нибудь может подгореть от такой невинной вещи, как дефолтные методы в интерфейсах.

#58
17:34, 4 сен. 2019

skalogryz
> почему нет?!
а действительно

#59
(Правка: 19:02) 18:49, 4 сен. 2019

Zefick
> Кто бы только мог подумать, что у кого-нибудь может подгореть от такой невинной
> вещи, как дефолтные методы в интерфейсах.
почему нет - собственно форум для этого и создан! обсуждать технологии! чтобы пригорало у всех!
как по мне, так вещь вредная. (не вызовет ли это конфликт имён?! особенно там где используются виртуальные методы для реализации интерфейса)
но, может быть, во мне просто говорит ретроградство?!
Zefick
> Кто бы только мог подумать, что у кого-нибудь может подгореть от такой невинной
> вещи, как дефолтные методы в интерфейсах.

на форуме выбор не богат: либо ты обсуждает женский интерфейс, либо шарповский
да, и ещё есть крестопроблемы

Нихао
> а действительно
это же не вопрос технологии, а вопрос логики нового типа сообщений. Т.е. что означает Warning() - и может ли он быть передан в Notify()?
например. Нет у нас дефолтных методов, мы решаем вопрос таким путём:
interface IListener
{
    void Notify(string message);
}

interface IListenerEx
{
    void Warning(string message, int warningLevel)
}

NotifyWarning( string message, int level)
{
   foreach ( IListener l in subs)
   {
      IListenerEx lex = l as IListerenEx; // вот тут как раз "цена" для проверки нового контракта
                                          // "as" не совсем бесплатен.
                                          // поддерживает ли тот же самый интерфейс новый метод
      if (lex!=null) lex.Warning(message, level)
      else {
        // а тут нужно уже решить, вызывать Notify или нет
        // тот же самый вопрос нужно решать и при использовании
        // дефолтной имплементации
        l.Notify(message);
      }
   }
}

Итого, если Warning() имеет декаротивную функцию. Т.е. помогает Listener-у "оформить" warning каким-то особым образом, то дефолтовое решение вполне может вызывать Notify()
Но если Warning несёт в себе иную информацию, которая не должна быть доступна в Notify(), то дефолтовая имплементация может просто ничего не делать.

Ваш, Кэп!

Страницы: 1 2 3 4 5 6 7 Следующая »
ФлеймФорумПрограммирование