Я считаю, что это только запутывает код.
Вспомним букву I в SOLID: интерфейс — это аспект поведения. У компонента может быть много аспектов, но они должны быть разделены.
Здравствуйте, dmitry_npi, Вы писали:
_>Я считаю, что это только запутывает код. _>Вспомним букву I в SOLID: интерфейс — это аспект поведения. У компонента может быть много аспектов, но они должны быть разделены.
_>Кроме очевидных исключений типа _>
_>IEnumerable<T>: IEnumerable
_>
И чуть менее очевидные
ICollection : IEnumerable
IList : ICollection
Наследование интерфейсов с одной стороны необязательное, с другой стороны иногда упрощает код и понимание. Просто знаешь что если что-то реализует IList, то оно уже точно и перечислимо и коллекцией является, а не проверяешь каждый раз, что ThisSuperList реализует и IList и ICollection и IEnumerable.
Ну и банально — ты на вход принимаешь IList, и можешь напрямую использовать его и как IEnumerable, что логично.
С другой стороны, злоупотребление таким наследованием тоже не полезно.
Здравствуйте, dmitry_npi, Вы писали:
_>Я считаю, что это только запутывает код. _>Вспомним букву I в SOLID: интерфейс — это аспект поведения. У компонента может быть много аспектов, но они должны быть разделены.
Довольно сложно разделить концепцию коллекции, у которой есть Count, есть способ перебора элементов, и есть обращение по индексу, на ортогональные категории.
_>Кроме очевидных исключений типа _>
_>IEnumerable<T>: IEnumerable
_>
Вот как раз это исключение мне кажется максимально неочевидным. Именно это наследование стоило бы выкинуть к хренам, т.к. при наличии генерикового IEnumerable обычный только путается под ногами.
Так что это — не пример удачной иерархии интерфейсов, а компромисс между "хотим сделать удобный интерфейс для современных языков" и "боимся, что за нами не успеют авторы устаревших языков".
Сейчас IEnumerable — это ненужное legacy. Если бы у MS были средства на выпуск сразу второй версии дотнет, то этого ужаса бы нам не потребовалось.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: [ООП] Наследование интерфейсов друг от друга
Здравствуйте, 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]: [ООП] Наследование интерфейсов друг от друга
Здравствуйте, Serginio1, Вы писали: S> IEnumerable позволяет избавиться от рефлексии когда нужно привести тип к IEnumerable в каком то общем методе вместо
S>
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, dmitry_npi, Вы писали:
_>>Я считаю, что это только запутывает код. _>>Вспомним букву I в SOLID: интерфейс — это аспект поведения. У компонента может быть много аспектов, но они должны быть разделены. S>Довольно сложно разделить концепцию коллекции, у которой есть Count, есть способ перебора элементов, и есть обращение по индексу, на ортогональные категории.
_>>Кроме очевидных исключений типа _>>
_>>IEnumerable<T>: IEnumerable
_>>
S>Вот как раз это исключение мне кажется максимально неочевидным. Именно это наследование стоило бы выкинуть к хренам, т.к. при наличии генерикового IEnumerable обычный только путается под ногами. S>Так что это — не пример удачной иерархии интерфейсов, а компромисс между "хотим сделать удобный интерфейс для современных языков" и "боимся, что за нами не успеют авторы устаревших языков". S>Сейчас IEnumerable — это ненужное legacy. Если бы у MS были средства на выпуск сразу второй версии дотнет, то этого ужаса бы нам не потребовалось.
Я честно говоря не вижу проблем. Код ожидающий IEnumerable будет работать если ему передать IEnumerable<T>. Что еще нужно?
Программа – это мысли спрессованные в код
Re[4]: [ООП] Наследование интерфейсов друг от друга
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Serginio1, Вы писали: S>> IEnumerable позволяет избавиться от рефлексии когда нужно привести тип к IEnumerable в каком то общем методе вместо
S>>
Это пример. Мне нужно найти некий обобщенный интерфейс не привязанный к конкретному типу и вызвать его метод.
Например если бу не было IEnumerable мне бы пришлось вместо
if (obj is IEnumerable ie)
ie.GetEnumerator();
Пришлось бы сначала через цикл и GetGenericTypeDefinition() получить является он реализацией IEnumerable<>
а затем через рефлексию вызвать "GetEnumerator"
Здравствуйте, dmitry_npi, Вы писали:
_>Я считаю, что это только запутывает код. _>Вспомним букву I в SOLID: интерфейс — это аспект поведения. У компонента может быть много аспектов, но они должны быть разделены.
Почему? Поведение может быть сложным. Например, интерфейс может предполагать работу с ресурсами, которые надо вернуть или
очистить, и почему бы это интерфейс не отнаследовать от IDispose?
Здравствуйте, dmitry_npi, Вы писали:
_>Как вы считаете, является ли чем-то полезным наследование интерфейсов типа такого?
Да.
_>Я считаю, что это только запутывает код. _>Вспомним букву I в SOLID: интерфейс — это аспект поведения. У компонента может быть много аспектов, но они должны быть разделены.
А что, SOLID это непогрешимая истина какая-то? Мне он никогда не нравился. Дело не в том, что его положения неправильны — как раз, чаще всего, они неплохо описывают хороший код. Дело в том, что как объяснение (того, как хороший код писать) он оооооочень плохое объяснение.
Re[5]: [ООП] Наследование интерфейсов друг от друга
Здравствуйте, Serginio1, Вы писали: S>Это пример. Мне нужно найти некий обобщенный интерфейс не привязанный к конкретному типу и вызвать его метод.
По-прежнему не понимаю, зачем вам вызывать метод, про который вы ничего не знаете. S>Например .Net Core, AppDomain, WCF, RPC маршалинг по Tcp/Ip свой велосипед
Ну, так стало немножко более понятно. Но не до конца.
В принципе, когда вы идёте в dynamic — да, это мир бестиповых операций.
Но не очень понятно, чем вас спасает IEnumerable — на все случаи generic-интерфейсов не напасёшься их нетипизированных аналогов.
Кроме того, скорее всего, ваш код работает некорректно.
Что будет, если я реализую одновременно IEnumerable<string> и IEnumerable<int>?
Вменяемая реализация позволит пользователю явно выбрать, по кому из них итерироваться. IEnumerable — это потеря информации.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[6]: [ООП] Наследование интерфейсов друг от друга
Здравствуйте, Sinclair, Вы писали:
S>Но не очень понятно, чем вас спасает IEnumerable — на все случаи generic-интерфейсов не напасёшься их нетипизированных аналогов. S>Кроме того, скорее всего, ваш код работает некорректно. S>Что будет, если я реализую одновременно IEnumerable<string> и IEnumerable<int>? S>Вменяемая реализация позволит пользователю явно выбрать, по кому из них итерироваться. IEnumerable — это потеря информации.
Если ты реализуешь IEnumerable<string> и IEnumerable<int> то и определяешь IEnumerable.
И IEnumerable должен так же работать как и для конкретного типа. Иначе это некорректная реализация.
А если тип известен, то просто не нужно приводить к нужному типу, а для структур нет боксинга.
Но вот кода тип объекта заранее не известен, то тут спасают не дженерики.
И таких вещей куча и маленькая тележка. В тех е универсальных сериализаторах, десериализаторах.
С развитой иерархией объектов у которых есть свойство типа object итд.
и солнце б утром не вставало, когда бы не было меня
Re[7]: [ООП] Наследование интерфейсов друг от друга
Здравствуйте, Serginio1, Вы писали: S> Если ты реализуешь IEnumerable<string> и IEnumerable<int> то и определяешь IEnumerable. S>И IEnumerable должен так же работать как и для конкретного типа. Иначе это некорректная реализация.
Если ты реализуешь абстрактный proxy для произвольного кода, то он должен позволять вызывать произвольные интерфейсы.
А не только генериковые интерфейсы, у которых есть не-генерик аналог.
Ну, вот с IEnumerable<T> вам "повезло". А что вы будете делать с интерфейсами, у которых нет вот этого вот дуализма?
Если у вас нет решения — то ваше решение непригодно в продакшн.
Если есть — то ваше решение прекрасно заработает и в гипотетическом дотнете, у которого нету не-генерик IEnumerable вовсе.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: [ООП] Наследование интерфейсов друг от друга
Здравствуйте, Sinclair, Вы писали:
S>Сейчас IEnumerable — это ненужное legacy. Если бы у MS были средства на выпуск сразу второй версии дотнет, то этого ужаса бы нам не потребовалось.
Это не принципиальное решение, а уступка compatibility. Вопрос ТС же был о принципах.
Здравствуйте, dmitry_npi, Вы писали:
_>Как вы считаете, является ли чем-то полезным наследование интерфейсов типа такого?
в терминах java правильно говорить расширяет (extends)
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[3]: [ООП] Наследование интерфейсов друг от друга
Здравствуйте, Pavel Dvorkin, Вы писали: PD>Это не принципиальное решение, а уступка compatibility. Вопрос ТС же был о принципах.
Согласен. Просто пример с IEnumerable/IEnumerable<T> нерелевантен с т.з. вопроса ТС.
А так — совершенно нормально иметь вот такие сложные взаимоотношения интерфейсов.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[8]: [ООП] Наследование интерфейсов друг от друга
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Serginio1, Вы писали: S>> Если ты реализуешь IEnumerable<string> и IEnumerable<int> то и определяешь IEnumerable. S>>И IEnumerable должен так же работать как и для конкретного типа. Иначе это некорректная реализация. S>Если ты реализуешь абстрактный proxy для произвольного кода, то он должен позволять вызывать произвольные интерфейсы. S>А не только генериковые интерфейсы, у которых есть не-генерик аналог. S>Ну, вот с IEnumerable<T> вам "повезло". А что вы будете делать с интерфейсами, у которых нет вот этого вот дуализма? S>Если у вас нет решения — то ваше решение непригодно в продакшн. S>Если есть — то ваше решение прекрасно заработает и в гипотетическом дотнете, у которого нету не-генерик IEnumerable вовсе.
А вот с другими я и занимаюсь сексом и с удовольствием вспоминаю IEnumerable.
Просто у меня таких вещей бывает очень много. Конечно есть наработки и делаю универсальными которые надо переносить из проекта в проект.
Но каждый раз всплывает, что то новое.
и солнце б утром не вставало, когда бы не было меня
Re[2]: [ООП] Наследование интерфейсов друг от друга