Комментарии 7
По поводу последнего момента. Надо сразу переходить к интерфейсам раз уж такое дело
IList<int> list = new List<int>();
del.
Бонус 2 - обе реализации работают одинаково в dotnetfiddle (.Net 9), так как 'needToStopEnumeration = true
', а вот с 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>
И никаких проблем
Если бы метод
SegmentsAsMemory
был не публичным, а приватным, то вашSegmentEnumerator
мог бы обойтись без реализации какого-либо интерфейса вообще,IsPrefixOf
работал бы с ним как с конкретным типом.При работе с интерфейсами аллокация памяти в куче не всегда неизбежна.
void DoSomething(IEnumerable<ReadOnlyMemory<
char
>> enumerable)
- будет боксинг при передаче реализующей интерфейс структуры.void DoSomething(TEnumerator enumerable) where TEnumerator: IEnumerable<ReadOnlyMemory<
char
>>
- структура не будет боксироваться.
Struct IEnumerator