Логика работы интерфейса IEnumerator и foreach
От: Власенко Анатолий Юрьевич Россия  
Дата: 04.06.03 13:44
Оценка:
Доброе время суток!

Из книг по C# (имеющихся у меня) и MSDN мне непонятен принцип
работы конструкции foreach с объектом класса, реализующего
интерфейс IEnumerator.

Конкретная проблема заключается в непонимании мной необходимости
реализации метода Reset интерфейса IEnumerator.
Т.е. должен ли я вызывать метод Reset самостоятельно, например из
метода MoveNext, либо foreach сделает это автоматически?

К этому вопросу подтолкнуло неожиданное (для меня) поведение
конструкции foreach, т.к. первый проход по элементам класса,
реализующего IEnumerator проходит как и ожидается, следующи же
вызов foreach не дает результатов, т.к. метод Reset не вызывался.

Заранее спасибо!!!
Поиски счастья — основной источник несчастья.
Re: Логика работы интерфейса IEnumerator и foreach
От: Lloyd Россия  
Дата: 04.06.03 14:23
Оценка:
Здравствуйте, Власенко Анатолий Юрьевич, Вы писали:

ВАЮ>Доброе время суток!


ВАЮ>Из книг по 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
От: Lloyd Россия  
Дата: 04.06.03 14:30
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Может я и ошибаюсь, но мне кажется, что такая конструкция удобней:


А>
А>    ArrayList array = new ArrayList();
А>    array.Add(1);
А>    ...
А>    IEnumerator pEnum = array.GetEnumerator();
А>    while(pEnum.MoveNext())
А>    {
А>        pEnum.Current;//Делай с ним что тебе нравится.
А>    }
А>


А>С уважением.


Тебе видимо платят построчно.
Re[3]: Логика работы интерфейса IEnumerator и foreach
От: Аноним  
Дата: 04.06.03 14:35
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Здравствуйте, Аноним, Вы писали:


L>Тебе видимо платят построчно.



Re: Логика работы интерфейса IEnumerator и foreach
От: orangy Россия
Дата: 04.06.03 14:42
Оценка:
Здравствуйте, Власенко Анатолий Юрьевич, Вы писали:

ВАЮ>К этому вопросу подтолкнуло неожиданное (для меня) поведение

ВАЮ>конструкции foreach, т.к. первый проход по элементам класса,
ВАЮ>реализующего IEnumerator проходит как и ожидается, следующи же
ВАЮ>вызов foreach не дает результатов, т.к. метод Reset не вызывался.
GetEnumerator должен каждый раз возвращать новый, свежий объект, енумерующий сначала. У тебя так?
... << RSDN@Home 1.0 beta 7a | Сейчас среда, 21:06, слушаю тишину >>
"Develop with pleasure!"
Re[4]: Логика работы интерфейса IEnumerator и foreach
От: Lloyd Россия  
Дата: 04.06.03 14:45
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Lloyd, Вы писали:


L>>Здравствуйте, Аноним, Вы писали:


L>>Тебе видимо платят построчно.



А>


Кода в три раза больше + дополнительная переменная + необходимость приведения типа + необходимость делать Dispose для энумератора.
Неужели ты это делаешь по своей воле и забесплатно?
Re[2]: Логика работы интерфейса IEnumerator и foreach
От: Lloyd Россия  
Дата: 04.06.03 14:45
Оценка:
Здравствуйте, orangy, Вы писали:

O>GetEnumerator должен каждый раз возвращать новый, свежий объект, енумерующий сначала. У тебя так?


Откуда у тебя информация про "должен"?
Re[5]: Логика работы интерфейса IEnumerator и foreach
От: Ведмедь Россия  
Дата: 04.06.03 14:51
Оценка:
L>Кода в три раза больше + дополнительная переменная + необходимость приведения типа + необходимость делать Dispose для энумератора.
L>Неужели ты это делаешь по своей воле и забесплатно?

Встряну с вопросом — А если у нас коллекция это COM коллекця, то при выхове Dispose Release вызывается? И соотвесвенно будут ли утечки в такой ситуации


IADsAccessControlList acl;
// инит acl

foreach( IADsAccessControlEntry ace in acl )
{
}
Да пребудет с тобой Великий Джа
Re[5]: Логика работы интерфейса IEnumerator и foreach
От: Аноним  
Дата: 04.06.03 15:01
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Кода в три раза больше + дополнительная переменная + необходимость приведения типа + необходимость делать Dispose для энумератора.


А я не боюсь трудностей.

L>Неужели ты это делаешь по своей воле и забесплатно?


Представь себе — просто по фану.
Re[6]: Логика работы интерфейса IEnumerator и foreach
От: mihailik Украина  
Дата: 04.06.03 15:35
Оценка:
В>Встряну с вопросом — А если у нас коллекция это COM коллекця, то при выхове Dispose Release вызывается? И соотвесвенно будут ли утечки в такой ситуации

Managed IEnumerable превращается при переходе к COM в IEnumVariant. И наоборот.

Подробнее, что там освобождается, а что нет — не скажу. Поэкспериментировать нужно.
... << RSDN@Home 1.0 beta 7a >>
Re[3]: Логика работы интерфейса IEnumerator и foreach
От: mihailik Украина  
Дата: 04.06.03 15:35
Оценка:
O>GetEnumerator должен каждый раз возвращать новый, свежий объект, енумерующий сначала. У тебя так?

L>Откуда у тебя информация про "должен"?


Можно такой вывод сделать на основе того, что для него вызывается Dispose. Значит они не подразумевают его по второму разу использовать.
... << RSDN@Home 1.0 beta 7a >>
Re[4]: Логика работы интерфейса IEnumerator и foreach
От: Vlasenko007 Россия  
Дата: 05.06.03 03:58
Оценка:
Здравствуйте, mihailik, Вы писали:

O>>GetEnumerator должен каждый раз возвращать новый, свежий объект, енумерующий сначала. У тебя так?


Нет, у меня возвращается один и тот же объет. Вот если бы где-то прочитать, что я действительно _должен_
возвращать новый, свежий объект, тогда другое дело, я бы так и делал.
А пока единственное что я увидел, это то, что возвращение нового объекта является рекомендуемой практикой,
а не требованием, и не более того.

L>>Откуда у тебя информация про "должен"?


M>Можно такой вывод сделать на основе того, что для него вызывается Dispose. Значит они не подразумевают его по второму разу использовать.


Спасибо за размышления, но повторюсь, я надеялся что просто что-то упустил-проглядел, а так получается что IEnumerator.Reset автоматом нигде не вызывается.
Поиски счастья — основной источник несчастья.
Re[5]: Логика работы интерфейса IEnumerator и foreach
От: Lloyd Россия  
Дата: 05.06.03 06:47
Оценка:
Здравствуйте, Vlasenko007, Вы писали:

V>Нет, у меня возвращается один и тот же объет. Вот если бы где-то прочитать, что я действительно _должен_

V>возвращать новый, свежий объект, тогда другое дело, я бы так и делал.
V>А пока единственное что я увидел, это то, что возвращение нового объекта является рекомендуемой практикой,
V>а не требованием, и не более того.

Да, но если использовать единственный энумератор, то тогда ты не сможешь использовать его во вложенном цикле.

V>Спасибо за размышления, но повторюсь, я надеялся что просто что-то упустил-проглядел, а так получается что IEnumerator.Reset автоматом нигде не вызывается.


Дык говорят же, что IDisposable.Dispose вызывается. Определи его и в нем вызывай резет.
Re[6]: Логика работы интерфейса IEnumerator и foreach
От: Vlasenko007 Россия  
Дата: 05.06.03 08:55
Оценка:
Здравствуйте, 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
От: Lloyd Россия  
Дата: 05.06.03 09:38
Оценка:
Здравствуйте, 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 возвращать энумератор в пул.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.