2009-08-13 42 views
7

जावा Iterator एस के साथ, मैंने hasNext विधि का उपयोग यह निर्धारित करने के लिए किया है कि पुनरावृत्ति में अधिक तत्व हैं (तत्व का उपभोग किए बिना) - इस प्रकार, hasNext "Peek" विधि की तरह है।क्या एक आईन्यूमेरेटर के लिए "हैसनेक्स्ट" विधि है?

मेरा प्रश्न: क्या सी 0 के जेनेरिक IEnumerator एस के साथ "hasNext" या "Peek" विधि जैसी कोई चीज़ है?

+5

आप संभवतः कैसे नहीं जानते? क्या यह संभव है कि आपने कभी http://msdn.microsoft.com/en-us/library/78dfe2yb.aspx नहीं देखा है? –

+0

श्री सॉंडर्स, इसे इंगित करने के लिए आपको बहुत बहुत धन्यवाद। – JaysonFix

उत्तर

15

नहीं, दुर्भाग्यवश ऐसा नहीं है।

तरीके::

IEnumerator<T> इंटरफ़ेस केवल निम्नलिखित सदस्यों को उजागर करता है

Dispose
MoveNext
Reset

prope rties:

Current

+1

धन्यवाद, एंड्रयू। – JaysonFix

+1

हम यहां IENumerable के बजाय, IENumerator ले रहे हैं, है ना? और * MoveNext के बजाय, निपटान पर होना चाहिए। –

+0

@Even - यिक्स, वह पोस्ट त्रुटियों से भरी थी! उन्हें इंगित करने के लिए धन्यवाद। –

33

नहीं, लेकिन सी # में आप बार-बार वर्तमान तत्व के लिए आगे बढ़ने के बिना पूछ सकते हैं। यह इसे देखने का एक अलग तरीका है।

यह एक .NET शैली IEnumerator लेने के लिए और एक जावा शैली Iterator वापस जाने के लिए एक सी # वर्ग लिखने के लिए भी कठिन नहीं होगा। व्यक्तिगत रूप से मुझे लगता है कि ज्यादातर मामलों में .NET शैली का उपयोग करना आसान है, लेकिन वहां हम जाते हैं :)

संपादित करें: ठीक है, यह पूरी तरह से अनचाहे है, लेकिन लगता है यह काम करेगा। यह कम से कम संकलित करता है :)

using System; 
using System.Collections; 
using System.Collections.Generic; 

// // Mimics Java's Iterable<T> interface 
public interface IIterable<T> 
{ 
    IIterator<T> Iterator(); 
} 

// Mimics Java's Iterator interface - but 
// implements IDisposable for the sake of 
// parity with IEnumerator. 
public interface IIterator<T> : IDisposable 
{ 
    bool HasNext { get; } 
    T Next(); 
    void Remove(); 
} 

public sealed class EnumerableAdapter<T> : IIterable<T> 
{ 
    private readonly IEnumerable<T> enumerable; 

    public EnumerableAdapter(IEnumerable<T> enumerable) 
    { 
     this.enumerable = enumerable; 
    } 

    public IIterator<T> Iterator() 
    { 
     return new EnumeratorAdapter<T>(enumerable.GetEnumerator()); 
    } 
} 

public sealed class EnumeratorAdapter<T> : IIterator<T> 
{ 
    private readonly IEnumerator<T> enumerator; 

    private bool fetchedNext = false; 
    private bool nextAvailable = false; 
    private T next; 

    public EnumeratorAdapter(IEnumerator<T> enumerator) 
    { 
     this.enumerator = enumerator; 
    } 

    public bool HasNext 
    { 
     get 
     { 
      CheckNext(); 
      return nextAvailable; 
     } 
    } 

    public T Next() 
    { 
     CheckNext(); 
     if (!nextAvailable) 
     { 
      throw new InvalidOperationException(); 
     } 
     fetchedNext = false; // We've consumed this now 
     return next; 
    } 

    void CheckNext() 
    { 
     if (!fetchedNext) 
     { 
      nextAvailable = enumerator.MoveNext(); 
      if (nextAvailable) 
      { 
       next = enumerator.Current; 
      } 
      fetchedNext = true;    
     } 
    } 

    public void Remove() 
    { 
     throw new NotSupportedException(); 
    } 

    public void Dispose() 
    { 
     enumerator.Dispose(); 
    } 
} 

public sealed class IterableAdapter<T> : IEnumerable<T> 
{ 
    private readonly IIterable<T> iterable; 

    public IterableAdapter(IIterable<T> iterable) 
    { 
     this.iterable = iterable; 
    } 

    public IEnumerator<T> GetEnumerator() 
    { 
     return new IteratorAdapter<T>(iterable.Iterator()); 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return GetEnumerator(); 
    } 
} 

public sealed class IteratorAdapter<T> : IEnumerator<T> 
{ 
    private readonly IIterator<T> iterator; 

    private bool gotCurrent = false; 
    private T current; 

    public IteratorAdapter(IIterator<T> iterator) 
    { 
     this.iterator = iterator; 
    } 

    public T Current 
    { 
     get 
     { 
      if (!gotCurrent) 
      { 
       throw new InvalidOperationException(); 
      } 
      return current; 
     } 
    } 

    object IEnumerator.Current 
    { 
     get { return Current; } 
    } 

    public bool MoveNext() 
    { 
     gotCurrent = iterator.HasNext; 
     if (gotCurrent) 
     { 
      current = iterator.Next(); 
     } 
     return gotCurrent; 
    } 

    public void Reset() 
    { 
     throw new NotSupportedException(); 
    } 

    public void Dispose() 
    { 
     iterator.Dispose(); 
    } 
} 
+0

+1 यह वास्तव में एक ही पैटर्न पर एक अलग ले लेता है। –

+0

(अगर कोई दिलचस्पी लेता है तो एडाप्टर को कोड करने में मुझे खुशी है, लेकिन मैं इसे अन्यथा नहीं करूँगा ...) –

+3

मुझे इसे देखने में दिलचस्पी होगी, जॉन। – JaysonFix

3

अंकुशकों को अक्सर आलसी मूल्यांकन किया जाता है, इसलिए हैसनेक्स्ट थोड़ा समझ में आता है।

1

आप इस Implementing Peek to IEnumerator and IEnumerator<> पर एक नज़र डालने का भी प्रयास कर सकते हैं। यह एक विस्तार विधि है जो Peek कार्यक्षमता को IENumerator में जोड़ती है। आशा करता हूँ की ये काम करेगा। :)

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^