В одной книге встретил вот такое высказывание:
Итераторы всех коллекций .NET Framework являются изменяемыми структурами. Это, с одной стороны, избавляет от дополнительного выделения памяти в управ- ляемой куче при проходе по коллекции, а с другой стороны, может привести к не- ожиданному результату. Попробуйте предугадать поведение следующего кода (листинг 4.8), а потом запустите его, чтобы проверить свою догадку. Листинг 4.8. Неочевидное поведение итераторов
var x = new {Items = new List<int> {1, 2, 3}.GetEnumerator()};
while (x.Items.MoveNext())
{
Console.WriteLine(x.Items);
}
Цикл действительно становится бесконечным. Однако, почему?
Есть ли еще какие-нибудь не очевидные вещи в итераторах?
x.Items это публичное поле объекта, при этом оно является структурой, а при обращении к таким полям создаётся временная переменная. То есть на самом деле этот код выглядит приблизительно так (сам код синтаксически не верен):
var x = new { Items = new List<int> { 1, 2, 3 }.GetEnumerator() };
while (var tmp = x.Items, tmp.MoveNext())
{
Console.WriteLine(x.Items);
}
То есть при каждой итерации while создаётся копия значения x.Items, которая и изменяется методом MoveNext(), но вот само x.Items остаётся прежним.
Вообще эти проблемы хорошо описаны в этой статье.
Современные инструменты для криптотрейдинга: как технологии помогают принимать решения
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости