AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: База знаний и проекты
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 31.05.2007, 12:04   #1  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от belugin Посмотреть сообщение
Еще два энумератора
А можно ли попросить написать краткую статью для недогадливых (типа меня) чем отличается енумератор от итератора и зачем они нужны?
__________________
полезное на axForum, github, vk, coub.
Старый 31.05.2007, 13:23   #2  
Gustav is offline
Gustav
Moderator
Аватар для Gustav
SAP
Лучший по профессии 2009
 
1,858 / 1152 (42) ++++++++
Регистрация: 24.01.2006
Адрес: Санкт-Петербург
Записей в блоге: 19
Цитата:
Сообщение от mazzy Посмотреть сообщение
А можно ли попросить написать краткую статью ... чем отличается енумератор от итератора и зачем они нужны?
Ее уже написали mfp сотоварищи

With reference to:
Inside Microsoft Dynamics™ AX 4.0 \Chapter 15. System Classes \The Collection Classes \Traversal


Traversal

You can traverse your collections by using either an enumerator or an iterator. When the collection classes were first introduced in Dynamics AX, the iterator was the only option. But because of a few obscure drawbacks that appear as hard-to-find errors, enumerators were added, and iterators were kept for backward compatibility. To highlight the subtle differences, the following code shows how to traverse a collection with both approaches.

X++:
List list = new List(Types::Integer);
ListIterator iterator;
ListEnumerator enumerator;
;
//Populate list.
...

//Traverse using an iterator.
iterator = new ListIterator(list);
while (iterator.more())
{
    print iterator.value();
    iterator.next();
}

//Traverse using an enumerator.
enumerator = list.getEnumerator();
while (enumerator.moveNext())
{
    print enumerator.current();
}

The first difference is the way in which the iterator and enumerator instances are created. For the iterator, you call new, and for the enumerator, you get an instance from the collection class by calling the getEnumerator method. In most cases, both approaches will work equally well. However, when the collection class resides on the opposite tier from the tier on which it is traversed, the situation is quite different. For example, if the collection resides on the client tier and is traversed on the server tier, the iterator approach fails because the iterator does not support cross-tier referencing. The enumerator does not support cross-tier referencing either, but it doesn't have to because it is instantiated on the same tier as the collection class. Traversing on the server tier using the client tier enumerator is quite network intensive, but the result is logically correct. Because some code is marked as Called From, meaning that it can run on either tier, depending on where it is called from, you could have broken logic if you use iterators, even if you test one execution path. In many cases, hard-to-track bugs such as this surface only when an operation is executed in batch mode.

NOTE: In earlier versions of Dynamics AX, this problem was even more pronounced because development and testing sometimes took place in two-tier environments, and this issue surfaces only in three-tier environments.

The second difference between iterators and enumerators is the way in which the traversing pointer moves forward. In the iterator approach, you must explicitly call both more and next; in the enumerator approach, the moveNext method handles these needs. Most developers have inadvertently implemented an endless loop at least once, simply because they forgot to move a pointer. This is not a significant problem, but it does cause an annoying interruption during the development phase.

If you always use the enumerator, you will not encounter either of the preceding issues. The only situation in which you cannot avoid using the iterator is when you must remove elements from a List collection. The following code shows how this is accomplished.

X++:
List list = new List(Types::Integer);
ListIterator iterator;
;
list.addEnd(100);
list.addEnd(200);
list.addEnd(300);

iterator = new ListIterator(list);
while (iterator.more())
{
    if (iterator.value() == 200)
        iterator.delete();
    iterator.next();
}
print list.toString(); //{100, 300}
pause;
P.S. Перевод Гугла
За это сообщение автора поблагодарили: MikeR (2).
Старый 31.05.2007, 13:54   #3  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от Gustav Посмотреть сообщение
Интересный сервис...
А может сделать нормальный перевод?

Т.е. главных проблем две:
1. передача данных между клиентом и сервером
2. удаление элементов в энумераторе?
__________________
полезное на axForum, github, vk, coub.
Старый 31.05.2007, 13:55   #4  
MikeR is offline
MikeR
MCT
Аватар для MikeR
MCBMSS
Лучший по профессии 2015
Лучший по профессии 2014
 
1,628 / 627 (24) +++++++
Регистрация: 28.11.2005
Адрес: просто землянин
Попробую внести свою лепту. Вот вкратце отличия
1 для того чтоб пользовать iterator его надо инициализить через new() а для enumerator этого не требуется, он использует текущую сущность
2 iterator плохо переносит клиент - серверные пересылы, впрочем как и enumerator но последнему не нужно инициализиться. Поэтому если пользовать iterator могут возникнуть проблемы.
3 это перебор значений в iterator и enumerator. Для enumerator достаточно moveNext() и пойдет перебор а для iterator нужно переводить курсор iterator.next() а многие это пропускают и получается бесконечный цикл.
4 но чтобы удалить значение из списка вам не обойтись без iterator
Старый 18.06.2008, 18:36   #5  
Hyper is offline
Hyper
Участник
Соотечественники
 
163 / 29 (1) +++
Регистрация: 09.10.2003
Цитата:
Сообщение от Gustav Посмотреть сообщение
The only situation in which you cannot avoid using the iterator is when you must remove elements from a List collection. The following code shows how this is accomplished.
X++:
List list = new List(Types::Integer);
ListIterator iterator;
;
list.addEnd(100);
list.addEnd(200);
list.addEnd(300);

iterator = new ListIterator(list);
while (iterator.more())
{
    if (iterator.value() == 200)
        iterator.delete();
    iterator.next();
}
print list.toString(); //{100, 300}
pause;
В коде логическая ошибка. Перед iterator.next() необходим else.
За это сообщение автора поблагодарили: Gustav (2).
Старый 18.06.2008, 19:06   #6  
Gustav is offline
Gustav
Moderator
Аватар для Gustav
SAP
Лучший по профессии 2009
 
1,858 / 1152 (42) ++++++++
Регистрация: 24.01.2006
Адрес: Санкт-Петербург
Записей в блоге: 19
Цитата:
Сообщение от Hyper Посмотреть сообщение
В коде логическая ошибка. Перед iterator.next() необходим else.
На самом деле результат одинаков и так, и так (по крайней мере в 3.0 SP4). Думаю, что класс ListIterator всё сам корректно обрабатывает и не делает казалось бы лишний next для уже удаленного элемента.

Что касается визуального восприятия кода, то добавление else, на мой взгляд, затуманит наглядность, так как глаз привык к шаблону вида:
X++:
while (iterator.more())
{
    // bla-bla-bla

    iterator.next();
}
А пряча продвижение указателя за else, можно потерять уверенность, что будут обойдены все элементы коллекции.
Но в любом случае все претензии по данному фрагменту - авторам "Inside"
Старый 19.06.2008, 13:12   #7  
Hyper is offline
Hyper
Участник
Соотечественники
 
163 / 29 (1) +++
Регистрация: 09.10.2003
Цитата:
Сообщение от Gustav Посмотреть сообщение
Думаю, что класс ListIterator всё сам корректно обрабатывает и не делает казалось бы лишний next для уже удаленного элемента.
В том-то и дело, что делает; это достаточно легко проверяется. AX 4.0.

В приведенном примере результат, разумеется, одинаков, но с итератором, стоящим на 300, в цикл мы никогда не попадаем.
Цитата:
Но в любом случае все претензии по данному фрагменту - авторам "Inside"
Ну да. Это я так, на заметку.

Последний раз редактировалось Hyper; 19.06.2008 в 13:15.
Теги
enumerator, iterator, x++, контейнер, полезное

 


Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 04:03.