2012-05-22 34 views
6

का परिपत्र गणना मेरे वर्तमान एप्लिकेशन में आदेश पदानुक्रम है।सी #: आईनेमेरेबल

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 समय-समय पर कहा जाता है, तो यह यात्रा राज्य स्टोर करने के लिए आवश्यक है।

उस परिपत्र गणना को कैसे कार्यान्वित करें?

  1. IEnumerator<T> इंटरफ़ेस का उपयोग करना:

    मैं दो समाधान मिल गया है। ऐसा लग रहा है:

    if (!_enumerator.MoveNext()) 
    { 
        _enumerator.Reset(); 
        _enumerator.MoveNext(); 
    } 
    
  2. परिपत्र IEnumerable<T> (yield हमेशा उसी क्रम) का उपयोग करना: Implementing A Circular Iterator

शायद इसे प्राप्त करने के और तरीके हैं। आप क्या उपयोग करने की सिफारिश करेंगे और क्यों?

उत्तर

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

मेरे मामले में, समय-समय पर 'निष्पादन' कहा जाता है, इसलिए पुनरावृत्ति स्थिति को स्टोर करना आवश्यक है। –

4
इसके बजाय IEnumerator इंटरफ़ेस से निपटने का

,

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

की तरह ऐसा करते हैं तो आपको इंडेक्स पर बहुत अधिक प्रवाह मिलेगा, मेरे मामले में, समय-समय पर 'निष्पादन' कहा जाता है, इसलिए पुनरावृत्ति स्थिति को संग्रहीत करना आवश्यक है। –

+0

अंत में मेरा समाधान देखें। आप संग्रह में इंडेक्स स्टोर कर सकते हैं और इसे इटेटरेटर –

0

मुझे लगता है, सबसे अधिक आरामदायक तरह से कस्टम प्रगणक के साथ कस्टम संग्रह को लागू करने और उस में परिपत्र तर्क संपुटित करने के लिए हो wil।

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