2012-05-22 2 views
6

현재 응용 프로그램에 명령 계층 구조가 있습니다.C# : IEnumerable의 순환 열거

public interface ICommand 
{ 
    void Execute(); 
} 

따라서 일부 명령은 상태 저장이며 일부 명령은 그렇지 않습니다.

명령 실행 중 일부 명령 구현을 위해 원형 방식으로 IEnumerable을 열거해야합니다.

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은 때때로 불리는 그래서 반복 상태를 저장하는 것이 필요하다.

순환 식 열거 형을 구현하는 방법은 무엇입니까? IEnumerator<T> 인터페이스를 사용하여

  1. :

    나는 두 가지 해결책을 발견했다. 그것은 같다 : 원형 IEnumerable<T> (yield 영원히 동일한 시퀀스)를 사용

    if (!_enumerator.MoveNext()) 
    { 
        _enumerator.Reset(); 
        _enumerator.MoveNext(); 
    } 
    
  2. : Implementing A Circular Iterator.

어쩌면 더 많은 방법이 있습니다. 무엇을 사용 하시겠습니까? 그 이유는 무엇입니까? 대신있는 IEnumerator 인터페이스를 다루는

답변

1
while (!stop) 
{ 
    foreach (var i in numbers) 
    { 
    // do something 
    } 
} 
+0

제 경우에는'Execute'가 때때로 호출되기 때문에 반복 상태를 저장해야합니다. –

4

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]; 
} 
+1

제 생각 엔 인덱스에 오버 플로우가 발생할 것 같습니다. –

+0

제 경우에는'Execute'가 때때로 호출되기 때문에 반복 상태를 저장해야합니다. –

+0

결국 내 해결책을보십시오. 컬렉션에 인덱스를 저장하고 iterator에 전달할 수 있습니다. –

0

제가 생각하기에 가장 편한 방법은 사용자 지정 열거 자와 사용자 지정 컬렉션을 구현하고 그 안에 원형 로직을 캡슐화하는 줘야 해. 당신은 항복을 반환하지 않고 원형 열거를 쓸 수 같은

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> {} 

뭔가 ...

-1

.

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; 
    } 
}