TGViewer
C# Heppard C# Heppard @csharp_gepard · 1.65K subscribers
Post #86 1.93K
Свой Enumerator #память

Могие почему-то боятся делать перечислители (Enumerator) для своих коллекций, выставляя наружу внутренние массивы List или Dictionary. Чуть более смелые разработчики, желая сохранить инкапсуляцию, выставляют из сущностей IEnumerable или даже более правильный IReadOnlyCollection, делая свои коллекции приватными, но доступными через свойство. А вот если нам нужно что-то сделать перед передачей элемента коллекции из сущности, то добро пожаловать в LINQ: коллеги просто возвращают IEnumerable где начинают городить в возвращаемом свойстве что-то вроде _collection.Select(id => new Actor(conext, id)).

Давайте не будем так делать. Перечислители писать легко, благодаря duck-typing'у, который только и требует от нас написать одно свойство (Current) и два метода (MoveNext и GetEnumerator). Для примера, вот так будет выглдяеть enumerator для ref struct (обратите внимание, что я использую современный синтакс C#).


public ref struct Enumerator(int[] collection, MyContext context) {
public readonly Result Current => new(context, collection[_index]);

private int _index = -1;

public bool MoveNext() => ++_index < collection.Length;
}


В нашей собственной коллекции мы можем также, как и выше, воспользоваться duck-typing'ом, банально реализовав метод GetEnumerator:


pubic class MyCollection {

private int[] _collection;
private MyContext _context;

...
public Enumerator GetEnumerator() => new(_collection, _context);
...
}


Таким образом мы решаем сразу несколько проблем:
1. Мы не выставляем наружу внутреннюю коллекцию.
2. Мы возвращаем нормальный enumerator в виде struct, который ничего не аллоцирует.
3. Мы не производим замыкание переменных (closure) при перечислении (см. свойство Current, где можно нагородить любую логику).

Код примера в комментариях, если я объяснил слишком туманно.
  • 👍 25
  • ❤ 1
More from @csharp_gepard
  1. Mar 13, 2026Ozon Tech Community .NET Meetup 24 марта, лофт Casa Picassa, 19:00 Ищем способы бороться с…
  2. Jan 20, 2026Ещё одна история про память #отдых Судя по комментариям специалистов и ценам на RAM в мага…
  3. Nov 25, 2025FastEnum #скорость Иногда нам нужно не просто быстро, а очень быстро. В этот момент в дело…
  4. Nov 20, 2025UnsafeAccessor #скорость Иногда возникает странное желание изменять приватные поля в класс…
  5. Nov 17, 2025Latency numbers every programmer should know Я всё время теряю эти циферки, особенно когда…
  6. Oct 29, 2025Dictionary.TryGetValue #скорость Уж сколько лет прошло и, вроде, все это знают. Но, тем не…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →