Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > .NET Frameworks (точка нет фреймворки) > C# (си шарп)
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 10.09.2016, 19:45   #1
BadCats
Пользователь
 
Аватар для BadCats
 
Регистрация: 31.01.2016
Сообщений: 67
Радость Цикл foreach при работе с коллекциями и массивами

Всем привет. Начал ищучение коллекцийи цикла foreach приминяемого для работы с ними.
Имеется банальный, так сказать тренировачный пример:
Модуль element.cs
Код:
// Экземпляры этого класса будет содержать коллекция - UserCollection. 
    public class Element
    {
        // Поля.
 
        private string name;
        private int field1;
        private int field2;
 
        // Конструктор.
        public Element(string s, int a, int b)
        {
            name = s;
            field1 = a;
            field2 = b;
        }
 
        // Свойства.
 
        public int Field1
        {
            get { return field1; }
            set { field1 = value; }
        }
 
        public int Field2
        {
            get { return field2; }
            set { field2 = value; }
        }
 
        public string Name
        {
            get { return name; }
            set { name = value; }
        }
    }
модуль UserCollections.cs
Код:
// Класс UserCollection коллекция (набор) объектов класса Element.
    // Для применения foreach, необходимо, чтобы класс реализовывал интерфейс - IEnumerable.
    public class UserCollection : IEnumerable, IEnumerator
    {
        public Element[] elementsArray = null;
 
        public UserCollection()
        {
            elementsArray = new Element[4];
            elementsArray[0] = new Element("A", 1, 10);
            elementsArray[1] = new Element("B", 2, 20);
            elementsArray[2] = new Element("C", 3, 30);
            elementsArray[3] = new Element("D", 4, 40);
        }
        
        // Указатель текущей позиции элемента в массиве.
        int position = -1;  
 
        // ------------------------------------------------------------------------------------------------------------------
        // Реализация интерфейса IEnumerator.
 
        // Передвинуть внутренний указатель (position) на одну позицию.
        public bool MoveNext()
        {
            if (position < elementsArray.Length - 1)
            {
                position++;
                return true;
            }
            else
            {
                return false;
            }
        }
 
        // Установить указатель (position) перед началом набора.
        public void Reset()
        {
            position = -1;
        }
 
        // Получить текущий элемент набора. 
        public object Current
        {
            get { return elementsArray[position]; }
        }
 
        // -----------------------------------------------------------------------------------------------------------------
        // Реализация интерфейса - IEnumerable.
 
        IEnumerator IEnumerable.GetEnumerator()
        {
            return this as IEnumerator;
        }
    }
Модуль Program.cs
Код:
UserCollection myCollection = new UserCollection();
         
            // Используем foreach, для обращения к каждому объекту Element внутри массива myCollection. 
            foreach (Element element in myCollection)
            {
                Console.WriteLine("Name: {0}  Field1: {1} Field2: {2}", element.Name, element.Field1, element.Field2);
            }
 
            //myCollection.Reset(); // Убрать комментарий для проверки.
 
            Console.Write(new string('-', 29) + "\n");
 
            // Используем foreach, для повторного обращения к каждому объекту Element внутри массива myCollection.
            foreach (Element element in myCollection)
            {
                Console.WriteLine("Name: {0}  Field1: {1} Field2: {2}", element.Name, element.Field1, element.Field2);
            }
 
            Console.Write(new string('-', 29) + "\n");
при работе которго, на экран выводится следующие: см. рисунок 1
Если же мы снимаем комментарий со строки(см рисунок 2)
Код:
myCollection.Reset();
- которая сбрасывает указатель position до -1 т.е ха пределлы нашей коллекции, что и дает возможность выванному после этого еще одному циклу foreach заново пробежатся по нашей коллекции и извлекая ее элементы, а затем при кажой итерации помещая каждый элемент в переменную итерации - выводить на экран значение извлеченного элемента коллекции. А когда вышеописаннная строка была закоментированна, то после первого цикла foreach, второй не срабатывал - т.к указатель position уже и так был в конце нашей коллекции.
После этого автор видеокурса, который я смотрю предлагает рассмотреть работу цикла foreach вместе с массивом а не с коллекциями.
Код:
int [] array={1,2,3,4,5,6,7,8,9,10}
 
foreach(int titem in array)
{
Console.Writeline(item);
}
Затем копирует данный цикл foreach , и не вставляя между ними Reset(); - используя два цикла foreach "подряд" без промежутка в виде Reset();
Самое интрестное, что автор говорит, цитирую - "На самом деле, все массывы в C# - являются настоящими коллекциями. В C# не существует массивов - это всего лишь иллюзия и удобный синтаксис."
Аргументируя это вот чем:
Код:
public abstract class Array : ICloneable, IList, ICollection, IEnumerable, IStructuralComparable, IStructuralEquatable
- что класс Array реалезует интерфейс IEnumerable - здесь же на форуме я уже спрашивал об этом интерфейсе Содержимое интерфейса IEnumerable.
Но вот в чем мой вопрос:Почему в "обычных" коллекциях - т.е которые мы создаем сами нужно сбрасывать position для повторного проходп ро коллекции с помощью цикла foreach еще раз, а в обычном массиве, который по славам автора также является коллекцие - мы не производим этого действия? (правда в строение класса Array я не углублялся и не знаю, присутствует ли в нем вообще некий указатель? Может хоть и класс Array и реалезует интерфейс IEnumerable в нем (в классе) может не существовать подобного механизма - я не знаю)
Изображения
Тип файла: jpg Рисунок1.JPG (27.2 Кб, 55 просмотров)
Тип файла: jpg Рисунок2.JPG (34.3 Кб, 51 просмотров)
BadCats вне форума Ответить с цитированием
Старый 10.09.2016, 20:14   #2
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Потому что автор так реализовал.
В стандартных коллекциях как-то так:
Код:
    public List<T>.Enumerator GetEnumerator()
    {
         return new List<T>.Enumerator(this);
    }
Не надо в Помощи студентам создавать такие темы, особенно без указания языка в названии, для этого есть нормальные разделы.
http://www.programmersforum.ru/forumdisplay.php?f=55
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Старый 10.09.2016, 21:14   #3
BadCats
Пользователь
 
Аватар для BadCats
 
Регистрация: 31.01.2016
Сообщений: 67
По умолчанию

Цитата:
Сообщение от Alex11223 Посмотреть сообщение
Потому что автор так реализовал.
В стандартных коллекциях как-то так:
Код:
    public List<T>.Enumerator GetEnumerator()
    {
         return new List<T>.Enumerator(this);
    }
Не надо в Помощи студентам создавать такие темы, особенно без указания языка в названии, для этого есть нормальные разделы.
http://www.programmersforum.ru/forumdisplay.php?f=55
я иммею ввиду, почему при работе с массивом не нужно сбрасывать position
и да, извиняюсь за неправильное создантетемы
BadCats вне форума Ответить с цитированием
Старый 10.09.2016, 21:31   #4
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Во всех стандартных (и нормально реализованных не стандартных) коллекциях не нужно.

GetEnumerator обычно возвращает каждый раз новый объект, а не тот же самый.
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Старый 10.09.2016, 22:19   #5
come-on
Участник клуба
 
Регистрация: 21.10.2015
Сообщений: 1,361
По умолчанию

где вы таких авторов находите )))
come-on вне форума Ответить с цитированием
Старый 10.09.2016, 22:20   #6
BadCats
Пользователь
 
Аватар для BadCats
 
Регистрация: 31.01.2016
Сообщений: 67
По умолчанию

itvdn курс C# Essential урок 14
BadCats вне форума Ответить с цитированием
Старый 10.09.2016, 22:25   #7
come-on
Участник клуба
 
Регистрация: 21.10.2015
Сообщений: 1,361
По умолчанию

так а в чем цель примера? как 2 сущности в одну слить?
come-on вне форума Ответить с цитированием
Старый 10.09.2016, 22:28   #8
BadCats
Пользователь
 
Аватар для BadCats
 
Регистрация: 31.01.2016
Сообщений: 67
По умолчанию

неи, пример кода приведен для ролноты картины для отвечающих.
а вопрос почему в массиве, который по словам автора является коллекцие не нужно сбрасывать position, а в данном примере мы вручную вызываем reset() - в обычной коллекции, которую пишем самостоятельно?
Вот и все.
BadCats вне форума Ответить с цитированием
Старый 10.09.2016, 22:33   #9
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

потому что наша коллекция так реализована.
вам же выше объяснили что для обычных коллекций это не нужно, потому что там енумераторы чистые всегда.
у нас же енумератор всегда один.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 10.09.2016, 22:35   #10
come-on
Участник клуба
 
Регистрация: 21.10.2015
Сообщений: 1,361
По умолчанию

на то вам уже ответили, автор так вывернул...
напиши он хотябы так
IEnumerator IEnumerable.GetEnumerator()
{
return elementsArray.GetEnumerator();
}

то не надо было никакого ресета, а так он сделал то что я вам и написал, 2 в 1 и потому ресеты и пришлось расставлять между форычами
come-on вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Borland c++ ошибка при работе с массивами all_is_fear Помощь студентам 2 05.11.2011 23:11
Ошибка при работе с динамическими массивами GBAXA Общие вопросы Delphi 16 30.03.2011 09:28
процедуры и функции при работе с массивами irina belka Помощь студентам 1 12.12.2010 16:33
Переполненние стека при работе с массивами max&ilja Помощь студентам 2 22.12.2009 22:03
Цикл do while при работе со строками. Lazio Помощь студентам 7 11.10.2009 16:11