Задать вопрос
@kolkinv
Начинающий asp.net разработчик

Использование итераторов foreach?

Привет всем , суть вопроса :
есть цикл Foreach который собствено делает итерацию обьекта, кок понять почему нужно и когда нужно использовать интерфейсы с их методом GetEnumerator(); IEnumerable, IEnumerator, IEnumerable и IEnumerator
и в чем собствено разница использования этих интерфейсов вместе с циклом ? почему я не могу просто использовать цикл не прибегая к ним ?
  • Вопрос задан
  • 447 просмотров
Подписаться 2 Простой Комментировать
Решения вопроса 1
@cicatrix
было бы большой ошибкой думать
Интерфейсы нужны для того, чтобы с вашими собственными классами могли работать другие классы.
Например, вы реализовали собтсвенную коллекцию объектов со своей странной логикой. Допустим, вы хотите, чтобы по этой коллекции можно было бы пройтись циклом foreach, но изначально фрейморк понятия не имеет, каким образом осуществлять итерацию объектов внутри вашей коллекции. Вот тогда вы заявляете, что ваш класс реализует интерфейс IEnumerable, и предоставляет наружу реализацию этого интерфейса. Вот тогда фреймворк уже знает, как можно перебрать все элементы коллекции.
IEnumerable реализует и массив и список и словарь и связный список, то есть для того, чтобы вы могли пройтись по какому-либо классу при помощи foreach, этот класс обязан реализовывать IEnumerable. Считайте интефейс это "соглашение о сотрудничестве" между разными классами, в котором чётко определены правила взаимодействия.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
yarosroman
@yarosroman Куратор тега C#
C# the best
Nipheris
@Nipheris Куратор тега C#
Не должно быть duck typing в строго типизированном языке.

Это не duck typing, это структурная типизация. Проверки, как вы могли заметить, выполняются во время компиляции, а не выполнения - где ж тут duck typing? А то что наследоваться не обязательно от опр. интерфейса - так что ж тут плохого? Язык даёт синтаксический сахар в виде foreach, задача компилятора - сгенерить код, содержащий вызовы определённых методов с определённой сигнатурой, не более. Это задача именно что для структурной типизации, когда компилятору без разницы что у вас там за класс и какие у него интерфейсы, лишь бы можно было сгенерировать нужный код, и это правильно.
В конце-концов шаблоны в C++ работают точно также. И for-range циклы в C++ работают похожим образом (требуют чтобы были реализованы нужные методы, или свободные функции, принимающие аргумент нужного типа). В C# советуют реализовывать интерфейс, т.к. это даёт дополнительные возможности: а) передавать объект туда, где ожидается этот интерфейс (т.к. C# всё таки в основном язык с номинативной типизацией); б) контролировать что вы не забыли ничего реализовать.

Прочитал, но по факту, класс всё равно реализует IEnumerable, просто явно об этом не заявляет.

Не соглашусь, довольно спорный момент. Номинативная типизация говорит, что если только явное заявление о том, что мы реализуем какой-то интерфейс, даёт нам отношение is-a между классом и интерфейсом. Если мы НЕ говорим, что реализуем IEnumerable, то мы его НЕ реализуем, даже если у нас там такие же методы.

И да, разберитесь заодно в разнице между статической и строгой типизацией, если вы не оговорились в комментарии, а действительно не понимаете разницы.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы