Зачем реализовывать IEnumerable в вашем классе?
Если вы пишете класс, а ваш класс реализует интерфейс IEnumerable (универсальный (T) или нет), который вы разрешаете любому потребителювашего класса, чтобы перебрать свою коллекцию, не зная, как она структурирована.
LinkedList реализован не так, как Очередь, Стек, BinaryTree, HashTable, Graph и т. Д. Коллекция, представленная вашим классом, может быть структурирована по-разному.
Как "Потребитель "(если вы пишете класс, а ваш класс потребляет / использует-использует объект класса, который реализует IEnumerable), вы можете использовать его, не заботясь о том, как он реализован.Иногда потребительский класс не заботится о реализации - он просто хочет просмотреть все элементы (распечатать их, изменить их, сравнить их? И т. Д.)
(То есть, как потребитель, если ваша задачаперебирать все элементы в классе BinaryTree, и вы пропустили этот урок в Data-Structures-101 - если кодировщик BinaryTree реализовал IEnumberable - вам повезло! Вам не нужно открывать книгу и изучать, как пройтидерево - но просто используйте оператор foreach для этого объекта, и все готово.)
Как «производитель» (пишущий класс, содержащий структуру данных / коллекцию), вы, возможно, не хотите, чтобы потребители вашегокласс, чтобы справиться с тем, как он структурирован (возможно, они могут его сломать).Таким образом, вы можете сделать коллекцию частной и предоставить доступ только к общедоступному IEnumerator.
Она также может обеспечить некоторую однородность - у коллекции может быть несколько способов перебора элементов (PreOrder, InOrder, PostOrder, Breadth First)., Depth First и т. Д.) - но есть только 1 реализация для IEnumerable.Вы можете использовать это, чтобы установить способ по умолчанию для перебора коллекции.
Зачем использовать IEnumerable в вашем методе?
Если я напишу метод, который принимает коллекцию, выполняет итерации по ней и выполняет действия с элементами (объединяет их? Сравниваетих? и т. д.) почему я должен ограничивать себя одним типом коллекций?
Написание этого метода public void Sum(List<int> list) {...}
для суммирования всех элементов в коллекции означает, что я могу только получить список и суммировать его.Запись этого public void Sum(IEnumerable<int> collection) {...}
означает, что я могу взять любой объект, который реализует IEnumberable (списки, очереди, стеки и т. Д.), А также суммировать все их элементы.
Другие вопросы
Есть также проблемы отложенного выполнения и неуправляемых ресурсов.IEnumerable использует синтаксис yield, который означает, что вы просматриваете каждый элемент отдельно и можете выполнять все виды вычислений до и после.И опять же, это происходит один за другим, поэтому вам не нужно хранить всю коллекцию при запуске.Вычисления фактически не будут выполняться, пока не начнется перечисление (то есть, пока вы не запустите цикл foreach).И это может быть полезным и более эффективным в определенных случаях.Например, ваш класс может не хранить какую-либо коллекцию в памяти, а выполнять итерацию по всем файлам, существующим в определенном каталоге, или элементам в определенной БД, или другим неуправляемым ресурсам.IEnumerable может вмешаться и сделать это за вас (вы также можете сделать это без IEnumerable, но IEnumberable «подходит» концептуально, плюс он дает вам возможность использовать объект, созданный в цикле foreach).