सी # में फॉरवर्ड लूप कैसे काम करते हैं? [बन्द है]


86

किस प्रकार के वर्ग foreachलूप का उपयोग कर सकते हैं ?


5
आप एक अलग स्वीकार किए गए उत्तर को चुनना चाहते हैं, क्योंकि आपके द्वारा चुना गया वास्तव में सही उत्तर का प्रतिनिधि नहीं है।
जॉर्ज स्टॉकर

जवाबों:


162

दरअसल, कड़ाई से बोलना, आपको केवल foreachएक सार्वजनिक GetEnumerator()विधि का उपयोग करना होगा जो किसी bool MoveNext()विधि और ? Current {get;}संपत्ति के साथ कुछ देता है । हालाँकि, इसका सबसे सामान्य अर्थ है "कुछ ऐसा है जो लागू करता है IEnumerable/ IEnumerable<T>, लौट रहा है a IEnumerator/ IEnumerator<T>

निहितार्थ रूप से, यह कुछ भी है कि औजार शामिल ICollection/ ICollection<T>, इस तरह की तरह कुछ के रूप में Collection<T>, List<T>, सरणियों ( T[]), आदि किसी भी मानक "डेटा के संग्रह" तो आम तौर पर समर्थन करेंगे foreach

पहले बिंदु के सबूत के लिए, निम्नलिखित ठीक काम करता है:

using System;
class Foo {
    public int Current { get; private set; }
    private int step;
    public bool MoveNext() {
        if (step >= 5) return false;
        Current = step++;
        return true;
    }
}
class Bar {
    public Foo GetEnumerator() { return new Foo(); }
}
static class Program {
    static void Main() {
        Bar bar = new Bar();
        foreach (int item in bar) {
            Console.WriteLine(item);
        }
    }
}

यह कैसे काम करता है?

थोरा की तरह एक फॉरेस्ट लूप foreach(int i in obj) {...}:

var tmp = obj.GetEnumerator();
int i; // up to C# 4.0
while(tmp.MoveNext()) {
    int i; // C# 5.0
    i = tmp.Current;
    {...} // your code
}

हालाँकि, वहाँ भिन्नताएँ हैं। उदाहरण के लिए, यदि एन्यूमरेटर (tmp) समर्थन करता है IDisposable, तो इसका उपयोग भी (समान using) किया जाता है ।

घोषणा के प्लेसमेंट में अंतर पर ध्यान देंint i " अंदर (सी # 5.0) बनाम बाहर (ऊपर सी # 4.0) लूप। यदि आप iअपने कोड-ब्लॉक के अंदर एक अनाम विधि / लैम्ब्डा में उपयोग करते हैं तो यह महत्वपूर्ण है । लेकिन यह एक और कहानी है;


3
गहराई में जाने के लिए +1। मैं आमतौर पर उस सवाल के लिए गहराई से नहीं जाता हूं जो 'शुरुआती' सवाल हो सकता है क्योंकि यह नए प्रोग्रामर को भारी लगेगा।
जॉर्ज स्टॉकर

सच है, गॉर्टॉक - इसलिए मैंने सूची / सरणियों / आदि के बारे में सामान के साथ पालन किया।
मार्क Gravell

लूप वेरिएबल को निहित रनटाइम कास्टिंग का उल्लेख करना अच्छा होगा - प्रकार की असंगति अपवाद पैदा कर सकता है।
डैनियल इयरविकर

3
मत भूलो: जब फॉर्च्यूनर के साथ एक सरणी का उपयोग करते हुए कंपाइलर एक सरल बनाता है for-loop(आईएल के साथ काम करते समय आप इसे देख सकते हैं)।
फेलिक्स के।

1
@ मारक ग्रेवेल: ठीक है, मस्त! मैंने पोस्ट को अधिक स्पष्ट करने के लिए संपादित किया - कम से कम मेरे लिए। सभी प्लेसमेंट के बाद केवल C # 5.0 में महत्वपूर्ण नहीं है, यह हमेशा महत्वपूर्ण है, केवल यह बदल गया है। मुझे आशा है कि आपको कोई आपत्ति नहीं है।
पॉल ग्रोके

7

से MSDN :

foreachबयान में प्रत्येक तत्व के लिए एम्बेडेड बयान के एक समूह को दोहराता एक सरणी या किसी वस्तु संग्रहforeachबयान संग्रह के माध्यम से पुनरावृति प्रयोग किया जाता है वांछित जानकारी प्राप्त करने के लिए, लेकिन संग्रह की सामग्री को बदलने के लिए अप्रत्याशित दुष्प्रभाव से बचने के लिए नहीं किया जाना चाहिए। (जोर मेरा)

इसलिए, यदि आपके पास एक सरणी है, तो आप सरणी के माध्यम से पुनरावृत्ति करने के लिए फॉर्च्यूमेंट स्टेटमेंट का उपयोग कर सकते हैं, जैसे:

 int[] fibarray = new int[] { 0, 1, 2, 3, 5, 8, 13 };
    foreach (int i in fibarray)
    {
        System.Console.WriteLine(i);
    }

आप इसे एक List<T>संग्रह के माध्यम से पुनरावृति के लिए भी उपयोग कर सकते हैं , जैसे:

List<string> list = new List<string>();

foreach (string item in list)
{
    Console.WriteLine(item);
}

4
MSDN ( msdn.microsoft.com/en-us/library/9yb8xew9(VS.80).aspx ) के अनुसार, पर्याप्त रूप से , ऑब्जेक्ट्स को IEnumerable को लागू करने की आवश्यकता नहीं है। कोई भी प्रकार जो GetEnumerator, MoveNext, Reset और Current को परिभाषित करता है, सही तरीका काम करेगा। अजीब, हुह?
सीन रीली

साफ। मुझे नहीं पता था। :-)
जॉर्ज स्टॉकर


2

यहाँ डॉक्स है: संग्रह वस्तुओं के साथ ऐरे के साथ मुख्य लेख

यह ध्यान रखना महत्वपूर्ण है कि "संग्रह तत्व का प्रकार पहचानकर्ता प्रकार के लिए परिवर्तनीय होना चाहिए"। यह कभी-कभी संकलन समय पर चेक नहीं किया जा सकता है और यदि संदर्भ प्रकार संदर्भ प्रकार के लिए उपलब्ध नहीं है, तो रनटाइम अपवाद उत्पन्न कर सकता है।

यह एक रनटाइम अपवाद उत्पन्न करेगा यदि फलों की टोकरी में एक गैर-सेब होता है, जैसे कि नारंगी।

List<Fruit> fruitBasket = new List<Fruit>() { new Apple(), new Orange() };
foreach(Apple a in fruitBasket)

यह सुरक्षित रूप से Enumerable.OfType का उपयोग करके केवल ऐपल्स की सूची को फ़िल्टर करता है

foreach(Apple a in fruitBasket.OfType<Apple>() )

-1
IList<ListItem> illi = new List<ListItem>();
ListItem li = null;

foreach (HroCategory value in listddlsubcategory)
{
    listddlsubcategoryext = server.getObjectListByColumn(typeof(HroCategory), "Parentid", value.Id);
    li = new ListItem();
    li.Text = value.Description;
    li.Value = value.Id.ToString();
    illi.Add(li);
    IList<ListItem> newilli = new List<ListItem>();
    newilli = SubCatagoryFunction(listddlsubcategoryext, "-->");
    foreach (ListItem c in newilli)
    {
        illi.Add(c);
    }
}

-1

इस विषय से संबंधित उपयोगी जानकारी MSDN पर भी पाई जा सकती है। उस लेख से सार लेना:

फॉर्च्यूस कीवर्ड एक संग्रह को शामिल करता है, संग्रह में प्रत्येक तत्व के लिए एक बार एम्बेडेड स्टेटमेंट निष्पादित करता है:

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

संकलक उपरोक्त उदाहरण में दिखाए गए फॉर्च लूप का इस निर्माण के समान अनुवाद करता है:

IEnumerator<int> enumerator = collection.GetEnumerator();
while (enumerator.MoveNext())
{
    var item = enumerator.Current;
    Console.WriteLine(item.ToString());
}

-2

आप यह कोशिश कर सकते हैं ...

List<int> numbers = new List<int>();
        numbers.Add(5);
        numbers.Add(15);
        numbers.Add(25);
        numbers.Add(35);

        Console.WriteLine("You are added total number: {0}",numbers.Count);
        foreach (int number in numbers)
        {
            Console.WriteLine("Your adding Number are: {0}", number);
        }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.