Как стать автором
Поиск
Написать публикацию
Обновить

Комментарии 7

По поводу последнего момента. Надо сразу переходить к интерфейсам раз уж такое дело

IList<int> list = new List<int>();

Бонус 2 - обе реализации работают одинаково в dotnetfiddle (.Net 9), так как 'needToStopEnumeration = true', а вот с false уже как вы и пишите.

Не знаю, как случилась эта опечатка. Да, должно быть `needToStopEnumeration = false`. Спасибо, поправил в статье.

А ещё можно вспомнить, что перечисление умеет в утиную типизацию и интерфейсы IEnumerable и IEnumerator строго говоря не нужны: https://habr.com/ru/articles/148905/

Но если мы хотим в LINQ, тогда да, придётся.

По поводу последнего примера с

private static bool MoveNextEnumerator(IEnumerator<int> enumerator)

можно предложить другое решение:

private static bool MoveNextEnumerator<T>(ref T enumerator) where T : struct, IEnumerator<int>

private static bool MoveNextEnumerator<T>(T enumerator) where T : class, IEnumerator<int>

И никаких проблем

  1. Если бы метод SegmentsAsMemory был не публичным, а приватным, то ваш SegmentEnumerator мог бы обойтись без реализации какого-либо интерфейса вообще, IsPrefixOf работал бы с ним как с конкретным типом.

  2. При работе с интерфейсами аллокация памяти в куче не всегда неизбежна.
    void DoSomething(IEnumerable<ReadOnlyMemory<char>> enumerable) - будет боксинг при передаче реализующей интерфейс структуры.
    void DoSomething(TEnumerator enumerable) where TEnumerator: IEnumerable<ReadOnlyMemory<char>> - структура не будет боксироваться.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий