C #: IEnumerable circular enumeration

My current application has a command hierarchy.

public interface ICommand { void Execute(); } 

So, some teams have state, some of them are not.

I need to list IEnumerable in a circular way for some implementation of the command at run time.

 public class GetNumberCommand : ICommand { public GetNumberCommand() { List<int> numbers = new List<int> { 1, 2, 3 }; } public void Execute() { // Circular iteration here. // 1 => 2 => 3 => 1 => 2 => 3 => ... } public void Stop() { // Log current value. (2 for example) } } 

Execute is called from time to time, so you need to maintain an iterative state.

How to implement this circular enumeration?

I found two solutions:

  • Using the IEnumerator<T> Interface It looks like this:

     if (!_enumerator.MoveNext()) { _enumerator.Reset(); _enumerator.MoveNext(); } 
  • Using a circular IEnumerable<T> ( yield forever the same sequence): Implementing a circular iterator .

There may be many more ways to achieve this. What do you recommend to use and why?

+6
source share
4 answers

Instead of using the IEnumerator interface

 foreach (var x in GetSomething()) { if (someCondition) break; } public IEnumerable<int> GetSomething() { List<int> list = new List<int>() { 1, 2, 3 }; int index=0; while (true) yield return list[index++ % list.Count]; } 
+4
source
 while (!stop) { foreach (var i in numbers) { // do something } } 
+1
source

I think the most convenient way is to implement a custom collection using a custom enumerator and encapsulate circular logic in it.

 class Collection<T> : IEnumerable<T> { bool circle; List<T> collection = new List<T>(); public IEnumerable<T> IEnumerable<T>.GetEnumerator() { if(circle) return new CustomEnumerator<T>(this); return circle.GetEnumerator(); } } class CustomEnumerator : Enumerator<T> {} 

something like that...

0
source

You can write a circular transfer without returning profitability.

  public class CircularEnumerable<T> : IEnumerable<T> { public CircularEnumerable (IEnumerable<T> sequence) { InfiniteLoop = sequence.Concat (this); } private readonly IEnumerable<T> InfiniteLoop; public IEnumerator<T> GetEnumerator () { return InfiniteLoop.GetEnumerator (); } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator () { return InfiniteLoop.GetEnumerator (); } } public class GetNumberCommand : ICommand { public GetNumberCommand() { List<int> numbers = new List<int> { 1, 2, 3 }; infiniteLoopOnNumbers = new CircularEnumerable<int>(numbers).GetEnumerator(); } IEnumerator<int> infiniteLoopOnNumbers; public void Execute() { infiniteLoopOnNumbers.MoveNext(); } public void Stop() { int value = infiniteLoopOnNumbers.Current; } } 
-1
source

Source: https://habr.com/ru/post/916325/


All Articles