Я нашел похожую тему:
Итераторы в C ++ (stl) и Java, есть ли концептуальная разница?
Который в основном касается Java-итератора (который похож на C #), который не может вернуться назад.
Так что здесь я хотел бы сосредоточиться на ограничениях - в C ++ итератор не знает своего предела, вы должны сами сравнить данный итератор с пределом. В C # итератор знает больше - вы можете не сравнивая ни с какой внешней ссылкой сказать, действителен итератор или нет.
Я предпочитаю способ C ++, потому что, имея итератор, вы можете установить любой итератор в качестве предела. Другими словами, если вы хотите получить только несколько элементов вместо всей коллекции, вам не нужно изменять итератор (в C ++). Для меня это более «чистый» (clear).
Но, конечно, MS знала об этом и C ++ при разработке C #. Так в чем же преимущества C # способа? Какой подход является более мощным (что приводит к более элегантным функциям на основе итераторов). Что мне не хватает?
Если у вас есть мысли по поводу итераторов C # и C ++ design , отличных от их пределов (границ), просьба также ответить.
Примечание : (на всякий случай), пожалуйста, придерживайтесь обсуждения исключительно технического характера. Нет C ++ / C # Flamewar.
редактирует
Как сказал Цаман: «Нет смысла выражать предел отдельно, потому что нет другого способа достичь этого, кроме как пройти по одному элементу за раз». Однако не так сложно создать итератор C #, который выполняет несколько шагов за раз, поэтому возникает вопрос: есть ли преимущество наличия явного итератора предела (как в C ++)? Если да - что?
@ Jon
Edit1: допустим, у вас есть функция foo, которая что-то делает с итераторами (пример очень наивный!)
void foo(iter_from,iter_end) // C++ style
void foo(iter) // C# style
А теперь вы хотите вызвать функциональную панель для всех элементов, кроме последних 10.
bar(iter_from,iter_end-10); // C++ style
В C # (если я не ошибаюсь) вам придется предоставить дополнительный метод для этого итератора, чтобы изменить его предел , примерно так:
bar(iter.ChangeTheLimit(-10));
Edit2: После перечитывания вашего поста я чувствую принципиальную разницу. В C ++ вы работаете с итераторами коллекций, в C # вы работаете с коллекциями (итератор используется «внутри»). Если да, я все еще чувствую себя немного неловко с C # - вы выполняете итерацию коллекции, и когда вы находите интересный элемент, вы хотели бы передать все элементы от «сюда» до конца. В C ++ это очень просто и нет накладных расходов. В C # вы либо передаете итератор, либо коллекцию (если у последнего будут дополнительные вычисления). Я буду ждать вашего комментария: -)
@ Hans
Я не сравниваю яблоки и апельсины. Комп. теория здесь является общей, поэтому у вас есть алгоритм сортировки, разбиение и т. д. У вас есть понятие коллекции (или последовательности, как нравится Джону). Теперь - вопрос в том, как спроектировать доступ к элементам так, чтобы элегантный алгоритм был написан на C # или C ++ (или любом другом языке). Я хотел бы понять аргументацию "мы сделали это, потому что ...".
Я знаю .NET-итераторы и коллекции - это отдельные классы. Я знаю разницу между доступом к элементу и всей коллекции. Однако в C ++ наиболее общий способ работы с коллекцией - это работа с итераторами. Таким образом, вы можете работать со списком и вектором, несмотря на то, что эти коллекции совершенно разные. С другой стороны, в C # вы пишете
sort(IEnumerable<T> coll)
функция вместо
sort(IEnumerator<T> iter)
правильно? Так что в этом смысле, я думаю, вы не можете принять итераторы C # как итераторы C ++, потому что C # не выражает те же алгоритмы, что и C ++. Или, как указал Джон, - в C # вы предпочитаете преобразовывать коллекцию (Skip, Take) вместо смены итераторов.