[ООП] Наследование интерфейсов друг от друга
От: dmitry_npi Россия  
Дата: 31.01.24 07:56
Оценка:
Как вы считаете, является ли чем-то полезным наследование интерфейсов типа такого?

interface IService1
{
   void Foo();
}

interface IService2: IService1
{
  void Bar();
}


Я считаю, что это только запутывает код.
Вспомним букву I в SOLID: интерфейс — это аспект поведения. У компонента может быть много аспектов, но они должны быть разделены.

Кроме очевидных исключений типа
IEnumerable<T>: IEnumerable
Атмосферная музыка — www.aventuel.net
Re: [ООП] Наследование интерфейсов друг от друга
От: Jack128  
Дата: 31.01.24 08:06
Оценка:
Здравствуйте, dmitry_npi, Вы писали:

_>Кроме очевидных исключений типа

_>
_>IEnumerable<T>: IEnumerable
_>


Тут бы не помешало границу очевидности провести. А то она не очевидна.
Re: [ООП] Наследование интерфейсов друг от друга
От: vsb Казахстан  
Дата: 31.01.24 08:09
Оценка:
Здравствуйте, dmitry_npi, Вы писали:

_>Как вы считаете, является ли чем-то полезным наследование интерфейсов?


Безусловно. Вот наследование реализаций решительно не нужно.
Re: [ООП] Наследование интерфейсов друг от друга
От: fmiracle  
Дата: 31.01.24 08:17
Оценка: +1
Здравствуйте, dmitry_npi, Вы писали:

_>Я считаю, что это только запутывает код.

_>Вспомним букву I в SOLID: интерфейс — это аспект поведения. У компонента может быть много аспектов, но они должны быть разделены.

_>Кроме очевидных исключений типа

_>
_>IEnumerable<T>: IEnumerable
_>


И чуть менее очевидные
ICollection : IEnumerable

IList : ICollection



Наследование интерфейсов с одной стороны необязательное, с другой стороны иногда упрощает код и понимание. Просто знаешь что если что-то реализует IList, то оно уже точно и перечислимо и коллекцией является, а не проверяешь каждый раз, что ThisSuperList реализует и IList и ICollection и IEnumerable.
Ну и банально — ты на вход принимаешь IList, и можешь напрямую использовать его и как IEnumerable, что логично.

С другой стороны, злоупотребление таким наследованием тоже не полезно.
Отредактировано 05.02.2024 7:07 fmiracle . Предыдущая версия . Еще …
Отредактировано 31.01.2024 8:24 fmiracle . Предыдущая версия .
Re: [ООП] Наследование интерфейсов друг от друга
От: Sinclair Россия https://github.com/evilguest/
Дата: 31.01.24 10:52
Оценка: +2
Здравствуйте, dmitry_npi, Вы писали:

_>Я считаю, что это только запутывает код.

_>Вспомним букву I в SOLID: интерфейс — это аспект поведения. У компонента может быть много аспектов, но они должны быть разделены.
Довольно сложно разделить концепцию коллекции, у которой есть Count, есть способ перебора элементов, и есть обращение по индексу, на ортогональные категории.

_>Кроме очевидных исключений типа

_>
_>IEnumerable<T>: IEnumerable
_>

Вот как раз это исключение мне кажется максимально неочевидным. Именно это наследование стоило бы выкинуть к хренам, т.к. при наличии генерикового IEnumerable обычный только путается под ногами.
Так что это — не пример удачной иерархии интерфейсов, а компромисс между "хотим сделать удобный интерфейс для современных языков" и "боимся, что за нами не успеют авторы устаревших языков".
Сейчас IEnumerable — это ненужное legacy. Если бы у MS были средства на выпуск сразу второй версии дотнет, то этого ужаса бы нам не потребовалось.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: [ООП] Наследование интерфейсов друг от друга
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 31.01.24 11:01
Оценка:
Здравствуйте, Sinclair, Вы писали:

_>>Кроме очевидных исключений типа

_>>
_>>IEnumerable<T>: IEnumerable
_>>

S>Вот как раз это исключение мне кажется максимально неочевидным. Именно это наследование стоило бы выкинуть к хренам, т.к. при наличии генерикового IEnumerable обычный только путается под ногами.
S>Так что это — не пример удачной иерархии интерфейсов, а компромисс между "хотим сделать удобный интерфейс для современных языков" и "боимся, что за нами не успеют авторы устаревших языков".
S>Сейчас IEnumerable — это ненужное legacy. Если бы у MS были средства на выпуск сразу второй версии дотнет, то этого ужаса бы нам не потребовалось.

IEnumerable позволяет избавиться от рефлексии когда нужно привести тип к IEnumerable в каком то общем методе вместо

 while (objType!=null && objType != typeof(object))
 {
     if (objType.IsGenericType && 
         objType.GetGenericTypeDefinition() == typeof(IEnumerable<>))
         return true;
     objType = objType.BaseType;
 }
и солнце б утром не вставало, когда бы не было меня
Re[3]: [ООП] Наследование интерфейсов друг от друга
От: Sinclair Россия https://github.com/evilguest/
Дата: 31.01.24 11:16
Оценка:
Здравствуйте, Serginio1, Вы писали:
S> IEnumerable позволяет избавиться от рефлексии когда нужно привести тип к IEnumerable в каком то общем методе вместо

S>
S> while (objType!=null && objType != typeof(object))
S> {
S>     if (objType.IsGenericType && 
S>         objType.GetGenericTypeDefinition() == typeof(IEnumerable<>))
S>         return true;
S>     objType = objType.BaseType;
S> }
S>


Зачем вам такой код? Что он делает?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: [ООП] Наследование интерфейсов друг от друга
От: Qulac Россия  
Дата: 31.01.24 11:24
Оценка: +1
Здравствуйте, Sinclair, Вы писали:

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


_>>Я считаю, что это только запутывает код.

_>>Вспомним букву I в SOLID: интерфейс — это аспект поведения. У компонента может быть много аспектов, но они должны быть разделены.
S>Довольно сложно разделить концепцию коллекции, у которой есть Count, есть способ перебора элементов, и есть обращение по индексу, на ортогональные категории.

_>>Кроме очевидных исключений типа

_>>
_>>IEnumerable<T>: IEnumerable
_>>

S>Вот как раз это исключение мне кажется максимально неочевидным. Именно это наследование стоило бы выкинуть к хренам, т.к. при наличии генерикового IEnumerable обычный только путается под ногами.
S>Так что это — не пример удачной иерархии интерфейсов, а компромисс между "хотим сделать удобный интерфейс для современных языков" и "боимся, что за нами не успеют авторы устаревших языков".
S>Сейчас IEnumerable — это ненужное legacy. Если бы у MS были средства на выпуск сразу второй версии дотнет, то этого ужаса бы нам не потребовалось.

Я честно говоря не вижу проблем. Код ожидающий IEnumerable будет работать если ему передать IEnumerable<T>. Что еще нужно?
Программа – это мысли спрессованные в код
Re[4]: [ООП] Наследование интерфейсов друг от друга
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 31.01.24 11:51
Оценка:
Здравствуйте, Sinclair, Вы писали:

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

S>> IEnumerable позволяет избавиться от рефлексии когда нужно привести тип к IEnumerable в каком то общем методе вместо

S>>
S>> while (objType!=null && objType != typeof(object))
S>> {
S>>     if (objType.IsGenericType && 
S>>         objType.GetGenericTypeDefinition() == typeof(IEnumerable<>))
S>>         return true;
S>>     objType = objType.BaseType;
S>> }
S>>


S>Зачем вам такой код? Что он делает?


Это пример. Мне нужно найти некий обобщенный интерфейс не привязанный к конкретному типу и вызвать его метод.
Например если бу не было IEnumerable мне бы пришлось вместо


 if (obj is IEnumerable ie)
  ie.GetEnumerator();



Пришлось бы сначала через цикл и GetGenericTypeDefinition() получить является он реализацией IEnumerable<>
а затем через рефлексию вызвать "GetEnumerator"

Например .Net Core, AppDomain, WCF, RPC маршалинг по Tcp/Ip свой велосипед
и солнце б утром не вставало, когда бы не было меня
Отредактировано 31.01.2024 12:45 Serginio1 . Предыдущая версия .
Re: [ООП] Наследование интерфейсов друг от друга
От: Sharov Россия  
Дата: 31.01.24 11:55
Оценка:
Здравствуйте, dmitry_npi, Вы писали:

_>Я считаю, что это только запутывает код.

_>Вспомним букву I в SOLID: интерфейс — это аспект поведения. У компонента может быть много аспектов, но они должны быть разделены.

Почему? Поведение может быть сложным. Например, интерфейс может предполагать работу с ресурсами, которые надо вернуть или
очистить, и почему бы это интерфейс не отнаследовать от IDispose?
Кодом людям нужно помогать!
Re: [ООП] Наследование интерфейсов друг от друга
От: Alekzander  
Дата: 31.01.24 13:04
Оценка: +1
Здравствуйте, dmitry_npi, Вы писали:

_>Как вы считаете, является ли чем-то полезным наследование интерфейсов типа такого?


Да.

_>Я считаю, что это только запутывает код.

_>Вспомним букву I в SOLID: интерфейс — это аспект поведения. У компонента может быть много аспектов, но они должны быть разделены.

А что, SOLID это непогрешимая истина какая-то? Мне он никогда не нравился. Дело не в том, что его положения неправильны — как раз, чаще всего, они неплохо описывают хороший код. Дело в том, что как объяснение (того, как хороший код писать) он оооооочень плохое объяснение.
Re[5]: [ООП] Наследование интерфейсов друг от друга
От: Sinclair Россия https://github.com/evilguest/
Дата: 01.02.24 12:40
Оценка:
Здравствуйте, Serginio1, Вы писали:
S>Это пример. Мне нужно найти некий обобщенный интерфейс не привязанный к конкретному типу и вызвать его метод.
По-прежнему не понимаю, зачем вам вызывать метод, про который вы ничего не знаете.
S>Например .Net Core, AppDomain, WCF, RPC маршалинг по Tcp/Ip свой велосипед
Ну, так стало немножко более понятно. Но не до конца.
В принципе, когда вы идёте в dynamic — да, это мир бестиповых операций.
Но не очень понятно, чем вас спасает IEnumerable — на все случаи generic-интерфейсов не напасёшься их нетипизированных аналогов.
Кроме того, скорее всего, ваш код работает некорректно.
Что будет, если я реализую одновременно IEnumerable<string> и IEnumerable<int>?
Вменяемая реализация позволит пользователю явно выбрать, по кому из них итерироваться. IEnumerable — это потеря информации.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[6]: [ООП] Наследование интерфейсов друг от друга
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 01.02.24 13:55
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Но не очень понятно, чем вас спасает IEnumerable — на все случаи generic-интерфейсов не напасёшься их нетипизированных аналогов.

S>Кроме того, скорее всего, ваш код работает некорректно.
S>Что будет, если я реализую одновременно IEnumerable<string> и IEnumerable<int>?
S>Вменяемая реализация позволит пользователю явно выбрать, по кому из них итерироваться. IEnumerable — это потеря информации.

Если ты реализуешь IEnumerable<string> и IEnumerable<int> то и определяешь IEnumerable.
И IEnumerable должен так же работать как и для конкретного типа. Иначе это некорректная реализация.

А если тип известен, то просто не нужно приводить к нужному типу, а для структур нет боксинга.
Но вот кода тип объекта заранее не известен, то тут спасают не дженерики.
И таких вещей куча и маленькая тележка. В тех е универсальных сериализаторах, десериализаторах.
С развитой иерархией объектов у которых есть свойство типа object итд.
и солнце б утром не вставало, когда бы не было меня
Re[7]: [ООП] Наследование интерфейсов друг от друга
От: Sinclair Россия https://github.com/evilguest/
Дата: 05.02.24 05:00
Оценка:
Здравствуйте, Serginio1, Вы писали:
S> Если ты реализуешь IEnumerable<string> и IEnumerable<int> то и определяешь IEnumerable.
S>И IEnumerable должен так же работать как и для конкретного типа. Иначе это некорректная реализация.
Если ты реализуешь абстрактный proxy для произвольного кода, то он должен позволять вызывать произвольные интерфейсы.
А не только генериковые интерфейсы, у которых есть не-генерик аналог.
Ну, вот с IEnumerable<T> вам "повезло". А что вы будете делать с интерфейсами, у которых нет вот этого вот дуализма?
Если у вас нет решения — то ваше решение непригодно в продакшн.
Если есть — то ваше решение прекрасно заработает и в гипотетическом дотнете, у которого нету не-генерик IEnumerable вовсе.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: [ООП] Наследование интерфейсов друг от друга
От: Pavel Dvorkin Россия  
Дата: 05.02.24 05:09
Оценка: +1
Здравствуйте, Sinclair, Вы писали:

S>Сейчас IEnumerable — это ненужное legacy. Если бы у MS были средства на выпуск сразу второй версии дотнет, то этого ужаса бы нам не потребовалось.


Это не принципиальное решение, а уступка compatibility. Вопрос ТС же был о принципах.
With best regards
Pavel Dvorkin
Re: [ООП] Наследование интерфейсов друг от друга
От: Разраб  
Дата: 05.02.24 05:52
Оценка: +1
Здравствуйте, dmitry_npi, Вы писали:

_>Как вы считаете, является ли чем-то полезным наследование интерфейсов типа такого?

в терминах java правильно говорить расширяет (extends)
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[3]: [ООП] Наследование интерфейсов друг от друга
От: Sinclair Россия https://github.com/evilguest/
Дата: 05.02.24 06:26
Оценка: +2
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Это не принципиальное решение, а уступка compatibility. Вопрос ТС же был о принципах.
Согласен. Просто пример с IEnumerable/IEnumerable<T> нерелевантен с т.з. вопроса ТС.

А так — совершенно нормально иметь вот такие сложные взаимоотношения интерфейсов.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[8]: [ООП] Наследование интерфейсов друг от друга
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 05.02.24 07:13
Оценка: :)
Здравствуйте, Sinclair, Вы писали:

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

S>> Если ты реализуешь IEnumerable<string> и IEnumerable<int> то и определяешь IEnumerable.
S>>И IEnumerable должен так же работать как и для конкретного типа. Иначе это некорректная реализация.
S>Если ты реализуешь абстрактный proxy для произвольного кода, то он должен позволять вызывать произвольные интерфейсы.
S>А не только генериковые интерфейсы, у которых есть не-генерик аналог.
S>Ну, вот с IEnumerable<T> вам "повезло". А что вы будете делать с интерфейсами, у которых нет вот этого вот дуализма?
S>Если у вас нет решения — то ваше решение непригодно в продакшн.
S>Если есть — то ваше решение прекрасно заработает и в гипотетическом дотнете, у которого нету не-генерик IEnumerable вовсе.
А вот с другими я и занимаюсь сексом и с удовольствием вспоминаю IEnumerable.
Просто у меня таких вещей бывает очень много. Конечно есть наработки и делаю универсальными которые надо переносить из проекта в проект.
Но каждый раз всплывает, что то новое.
и солнце б утром не вставало, когда бы не было меня
Re[2]: [ООП] Наследование интерфейсов друг от друга
От: Pavel Dvorkin Россия  
Дата: 05.02.24 15:34
Оценка:
Здравствуйте, Разраб, Вы писали:

Р>в терминах java правильно говорить расширяет (extends)


Верно, но можно extends несколько интерфейсов, и тут уже просто не сказать "расширяет".
With best regards
Pavel Dvorkin
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.