Из книг по C# (имеющихся у меня) и MSDN мне непонятен принцип
работы конструкции foreach с объектом класса, реализующего
интерфейс IEnumerator.
Конкретная проблема заключается в непонимании мной необходимости
реализации метода Reset интерфейса IEnumerator.
Т.е. должен ли я вызывать метод Reset самостоятельно, например из
метода MoveNext, либо foreach сделает это автоматически?
К этому вопросу подтолкнуло неожиданное (для меня) поведение
конструкции foreach, т.к. первый проход по элементам класса,
реализующего IEnumerator проходит как и ожидается, следующи же
вызов foreach не дает результатов, т.к. метод Reset не вызывался.
Заранее спасибо!!!
Поиски счастья — основной источник несчастья.
Re: Логика работы интерфейса IEnumerator и foreach
Здравствуйте, Власенко Анатолий Юрьевич, Вы писали:
ВАЮ>Доброе время суток!
ВАЮ>Из книг по C# (имеющихся у меня) и MSDN мне непонятен принцип ВАЮ>работы конструкции foreach с объектом класса, реализующего ВАЮ>интерфейс IEnumerator.
ВАЮ>Конкретная проблема заключается в непонимании мной необходимости ВАЮ>реализации метода Reset интерфейса IEnumerator. ВАЮ>Т.е. должен ли я вызывать метод Reset самостоятельно, например из ВАЮ>метода MoveNext, либо foreach сделает это автоматически?
ВАЮ>К этому вопросу подтолкнуло неожиданное (для меня) поведение ВАЮ>конструкции foreach, т.к. первый проход по элементам класса, ВАЮ>реализующего IEnumerator проходит как и ожидается, следующи же ВАЮ>вызов foreach не дает результатов, т.к. метод Reset не вызывался.
ВАЮ>Заранее спасибо!!!
Нет, Reset не вызывается.
Но если Энумератор реализует IDisposable, то Dispose вызывается.
Re: Логика работы интерфейса IEnumerator и foreach
От:
Аноним
Дата:
04.06.03 14:28
Оценка:
Здравствуйте, Власенко Анатолий Юрьевич, Вы писали:
ВАЮ>...
Может я и ошибаюсь, но мне кажется, что такая конструкция удобней:
ArrayList array = new ArrayList();
array.Add(1);
...
IEnumerator pEnum = array.GetEnumerator();
while(pEnum.MoveNext())
{
pEnum.Current;//Делай с ним что тебе нравится.
}
С уважением.
Re[2]: Логика работы интерфейса IEnumerator и foreach
Здравствуйте, Власенко Анатолий Юрьевич, Вы писали:
ВАЮ>К этому вопросу подтолкнуло неожиданное (для меня) поведение ВАЮ>конструкции foreach, т.к. первый проход по элементам класса, ВАЮ>реализующего IEnumerator проходит как и ожидается, следующи же ВАЮ>вызов foreach не дает результатов, т.к. метод Reset не вызывался.
GetEnumerator должен каждый раз возвращать новый, свежий объект, енумерующий сначала. У тебя так?
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, Lloyd, Вы писали:
L>>Здравствуйте, Аноним, Вы писали:
L>>Тебе видимо платят построчно.
А>
Кода в три раза больше + дополнительная переменная + необходимость приведения типа + необходимость делать Dispose для энумератора.
Неужели ты это делаешь по своей воле и забесплатно?
Re[2]: Логика работы интерфейса IEnumerator и foreach
L>Кода в три раза больше + дополнительная переменная + необходимость приведения типа + необходимость делать Dispose для энумератора. L>Неужели ты это делаешь по своей воле и забесплатно?
Встряну с вопросом — А если у нас коллекция это COM коллекця, то при выхове Dispose Release вызывается? И соотвесвенно будут ли утечки в такой ситуации
Re[5]: Логика работы интерфейса IEnumerator и foreach
От:
Аноним
Дата:
04.06.03 15:01
Оценка:
Здравствуйте, Lloyd, Вы писали:
L>Кода в три раза больше + дополнительная переменная + необходимость приведения типа + необходимость делать Dispose для энумератора.
А я не боюсь трудностей.
L>Неужели ты это делаешь по своей воле и забесплатно?
Представь себе — просто по фану.
Re[6]: Логика работы интерфейса IEnumerator и foreach
В>Встряну с вопросом — А если у нас коллекция это COM коллекця, то при выхове Dispose Release вызывается? И соотвесвенно будут ли утечки в такой ситуации
Managed IEnumerable превращается при переходе к COM в IEnumVariant. И наоборот.
Подробнее, что там освобождается, а что нет — не скажу. Поэкспериментировать нужно.
... << RSDN@Home 1.0 beta 7a >>
Re[3]: Логика работы интерфейса IEnumerator и foreach
Здравствуйте, mihailik, Вы писали:
O>>GetEnumerator должен каждый раз возвращать новый, свежий объект, енумерующий сначала. У тебя так?
Нет, у меня возвращается один и тот же объет. Вот если бы где-то прочитать, что я действительно _должен_
возвращать новый, свежий объект, тогда другое дело, я бы так и делал.
А пока единственное что я увидел, это то, что возвращение нового объекта является рекомендуемой практикой,
а не требованием, и не более того.
L>>Откуда у тебя информация про "должен"?
M>Можно такой вывод сделать на основе того, что для него вызывается Dispose. Значит они не подразумевают его по второму разу использовать.
Спасибо за размышления, но повторюсь, я надеялся что просто что-то упустил-проглядел, а так получается что IEnumerator.Reset автоматом нигде не вызывается.
Поиски счастья — основной источник несчастья.
Re[5]: Логика работы интерфейса IEnumerator и foreach
Здравствуйте, Vlasenko007, Вы писали:
V>Нет, у меня возвращается один и тот же объет. Вот если бы где-то прочитать, что я действительно _должен_ V>возвращать новый, свежий объект, тогда другое дело, я бы так и делал. V>А пока единственное что я увидел, это то, что возвращение нового объекта является рекомендуемой практикой, V>а не требованием, и не более того.
Да, но если использовать единственный энумератор, то тогда ты не сможешь использовать его во вложенном цикле.
V>Спасибо за размышления, но повторюсь, я надеялся что просто что-то упустил-проглядел, а так получается что IEnumerator.Reset автоматом нигде не вызывается.
Дык говорят же, что IDisposable.Dispose вызывается. Определи его и в нем вызывай резет.
Re[6]: Логика работы интерфейса IEnumerator и foreach
Здравствуйте, Lloyd, Вы писали:
V>>Нет, у меня возвращается один и тот же объет. Вот если бы где-то прочитать, что я действительно _должен_ V>>возвращать новый, свежий объект, тогда другое дело, я бы так и делал.
L>Да, но если использовать единственный энумератор, то тогда ты не сможешь использовать его во вложенном цикле.
Согласен, аргументы понятны.
V>>Спасибо за размышления, но повторюсь, я надеялся что просто что-то упустил-проглядел, а так получается что IEnumerator.Reset автоматом нигде не вызывается.
L>Дык говорят же, что IDisposable.Dispose вызывается. Определи его и в нем вызывай резет.
Дак вот все, что я на данный момент понял, говорит о том, что Reset имеет смысл только для "ручной" работы с IEnumerator, т.е.
IEnumerator pEnum = array.GetEnumerator();
while(pEnum.MoveNext())
{
pEnum.Current;//Делай с ним что тебе нравится.
}
// Вызвать Reset для повторного прохода
pEnum.Reset();
// снова что-то делаем с IEnumerator
А особого смысла в вызове Reset из Dispose я не вижу, т.к. при возврате нового объекта на каждый запрос GetEnumerator, счетчик, ответственный за позицию, инициализируется так же как это делает Reset.
Поиски счастья — основной источник несчастья.
Re[7]: Логика работы интерфейса IEnumerator и foreach
Здравствуйте, Vlasenko007, Вы писали:
V>>>Спасибо за размышления, но повторюсь, я надеялся что просто что-то упустил-проглядел, а так получается что IEnumerator.Reset автоматом нигде не вызывается.
L>>Дык говорят же, что IDisposable.Dispose вызывается. Определи его и в нем вызывай резет. V>Дак вот все, что я на данный момент понял, говорит о том, что Reset имеет смысл только для "ручной" работы с IEnumerator, т.е.
V>
V> IEnumerator pEnum = array.GetEnumerator();
V> while(pEnum.MoveNext())
V> {
V> pEnum.Current;//Делай с ним что тебе нравится.
V> }
V> // Вызвать Reset для повторного прохода
V> pEnum.Reset();
V> // снова что-то делаем с IEnumerator
V>
V>А особого смысла в вызове Reset из Dispose я не вижу, т.к. при возврате нового объекта на каждый запрос GetEnumerator, счетчик, ответственный за позицию, инициализируется так же как это делает Reset.
Дык ты определись, ты будешь возвращать навый или повторно использовать существующий.
В принцыпе, можно вообще пул энумераторов организовать а на Dispose возвращать энумератор в пул.