Использует ли foreach IEnumerator/IEnumerable для встроенных типов?
Использует ли цикл foreach интерфейсы IEnumerator
а также IEnumerable
только для итерации объектов пользовательских типов (классов) или также для итерации встроенных типов (за кулисами)?
4 ответа
Foreach не зависит от IEnumerable
в качестве таких. Однако, если тип реализует его, цикл foreach сможет его перечислить (сопоставление на основе шаблона).
За кулисами нужно только GetEnumerator()
метод и перечислитель должны содержать Current
а также MoveNext()
,
Из MSDN:
Тип коллекции:
- Должен быть одного из типов: интерфейс, класс или структура.
- Должен включать метод экземпляра с именем GetEnumerator, который возвращает тип, например,
Enumerator
(объяснено ниже).Тип
Enumerator
(класс или структура) должны содержать:
- Свойство с именем Current, которое возвращает
ItemType
или тип, который может быть преобразован в него. Метод доступа к свойству возвращает текущий элемент коллекции.- Метод bool с именем MoveNext, который увеличивает счетчик элементов и возвращает значение true, если в коллекции больше элементов.
Из MSDN - Использование foreach с коллекциями
ОБНОВЛЕНО: см. Обновленную страницу MSDN для этого - Как: получить доступ к классу коллекции с помощью foreach (Руководство по программированию в C#).
Определите перечислитель, без IEnumerable объявления.!
public class WorkInfoEnumerator
{
List<WorkItem > wilist= null;
int currentIndex = -1;
public MyClassEnumerator(List<WorkItem > list)
{
wilist= list;
}
public WorkItem Current
{
get
{
return wilist[currentIndex];
}
}
public bool MoveNext()
{
++currentIndex;
if (currentIndex < wilist.Count)
return true;
return false;
}
}
public class WorkInfo
{
List<WorkItem > mydata = new List<WorkItem >();
public WorkInfoEnumerator GetEnumerator()
{
return new WorkInfoEnumerator(mydata);
}
}
Где-то в коде можно использовать:
WorkInfo wi = new WorkInfo();
foreach(WorkItem witem in wi)
{
}
foreach использует IEnumerable как для собственных, так и для пользовательских типов. Если вы посмотрите на System.Array, например, который является основой для всех типов массивов, он реализует IEnumerable.
for-each является языковой конструкцией и не различает пользовательские / встроенные типы.
для каждого не зависит от IEnumerable
, он использует сопоставление на основе шаблона. См. http://blogs.msdn.com/b/ericlippert/archive/2011/06/30/following-the-pattern.aspx