c# - सी#IEnumerable, IEnumerator रीसेट समारोह कॉल नहीं मिलता है




foreach (3)

गणना Reset कॉल नहीं करता है आपको एक गणक के एक नए उदाहरण को बनाने की आवश्यकता है, जिसका मतलब होगा कि गणक के लिए एक अलग वर्ग बनाना (यानी, IEnumerable और IEnumerator के लिए एक ही प्रकार का उपयोग न करें), नीचे दिए गए कोड की तरह:

public class StackOverflow_11475328
{
    class A : IEnumerable
    {
        int[] data = { 0, 1, 2, 3, 4 };

        public IEnumerator GetEnumerator()
        {
            return new AEnumerator(this);
        }

        class AEnumerator : IEnumerator
        {
            private A parent;
            private int position = -1;

            public AEnumerator(A parent)
            {
                this.parent = parent;
            }

            public object Current
            {
                get { return parent.data[position]; }
            }

            public bool MoveNext()
            {
                position++;
                return (position < parent.data.Length);
            }

            public void Reset()
            {
                position = -1;
            }
        }
    }
    public static void Test()
    {
        A a = new A();

        foreach (var item in a)
        {
            Console.WriteLine(item);
        }

        Console.WriteLine("--- First foreach finished. ---");

        foreach (var item in a)
        {
            Console.WriteLine(item);
        }
    }
}

मैं मूल रूप से मेरी कक्षा को विदेशी मुद्रा का प्रयोग करने में सक्षम बनाने की कोशिश कर रहा हूं मैंने इस ट्यूटोरियल को पढ़ा। एमएसडीएन यह बहुत सीधे आगे लगता है हालांकि, जब मुझे दूसरी बार पुनरावृति करना है तो मुझे एक समस्या है मैंने इसे डीबग किया; और यह पता चला कि यह Reset() फ़ंक्शन कॉल नहीं करता है

कक्षा

class A : IEnumerable, IEnumerator
{
    int[] data = { 0, 1, 2, 3, 4 };

    int position = -1;

    public object Current
    {
        get
        {
            return data[position];
        }
    }

    public bool MoveNext()
    {
        position++;
        return (position < data.Length);
    }

    public void Reset()
    {
        position = -1;
    }

    public IEnumerator GetEnumerator()
    {
        return (IEnumerator)this;
    }
}

जब मैं निम्नलिखित मुख्य फ़ंक्शन चलाता हूं; यह Reset() फ़ंक्शन कभी कॉल नहीं करता है। इसलिए, एक पाश के बाद मैं कभी भी फिर से मेरी कक्षा को फिर से सक्षम नहीं कर सकता।

मुख्य

static void Main(string[] args)
{
    A a = new A();

    foreach (var item in a)
    {
        Console.WriteLine(item);
    }

    Console.WriteLine("--- First foreach finished. ---");

    foreach (var item in a)
    {
        Console.WriteLine(item);
    }
}

आउटपुट:

0
1
2
3
4
--- First foreach finished. ---
Press any key to continue . . .

कोई विचार?


दोनों रीड और कार्लोस सही हैं। यहां एक तरीका है, int[] आप ऐसा कर सकते हैं, चूंकि IEnumerable और IEnumerable<int>

class A : IEnumerable
{ 
    int[] data = { 0, 1, 2, 3, 4 }; 

    public IEnumerator GetEnumerator() 
    { 
        return data.GetEnumerator(); 
    } 
} 

या, अधिक दृढ़ता से टाइप करने के लिए, आप IEnumerable के सामान्य रूप का उपयोग कर सकते हैं:

class A : IEnumerable<int>
{
    int[] data = { 0, 1, 2, 3, 4 };

    public IEnumerator<int> GetEnumerator()
    {
        return ((IEnumerable<int>)data).GetEnumerator();
    }

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

रीसेट () मूल रूप से एक गलती थी यदि संभव हो तो एक साफ गणक प्राप्त करने के लिए पहले से ही एक ज्ञात विधि है: GetEnumerator ()

यह विनिर्देश में एक आवश्यकता है कि इटरेटर ब्लॉक कार्यान्वयन (इटरेटर के लिए) इस पद्धति के लिए एक अपवाद फेंक देता है, इसलिए सामान्य तौर पर यह औपचारिक रूप से ज्ञात है कि यह काम करने की उम्मीद नहीं की जा सकती है, और बस: कोई भी कभी इसे कॉल नहीं करता है सच कहूँ तो, उन्हें एपीआई पर [अप्रचलित] भी चिह्नित करना चाहिए!

इसके अतिरिक्त, कई अनुक्रम गैर-पुनरावर्ती हैं एक नेटवर्कस्ट्रीम या एक यादृच्छिक संख्या जनरेटर पर बैठे Iterators के बारे में सोचो। चूंकि इटरेटर्स (सामान्य मामले में) को दोहराने योग्य नहीं होने की आवश्यकता है, इसलिए आपको लक्ष्य करना चाहिए, जहां संभव हो, उन्हें सबसे अधिक बार पुनरावृति करना चाहिए। शायद ToList () के माध्यम से बफरिंग अगर यह संभव नहीं है

"foreach" किसी भी बिंदु पर रीसेट () को शामिल नहीं करता है बस GetEnumerator (), MoveNext (), वर्तमान और डिस्पोज़ ()।







enumerator