2009-11-24 12 views
57

मैं इस आदेश के बारे में सोच रहा था कि सी # लूप में एक फोरच लूप System.Collections.Generic.List<T> ऑब्जेक्ट के माध्यम से लूप करता है।प्रत्येक लूप के लिए एक सूची <T> पर एक सी # के लिए किस क्रम में पुनरावृत्ति करता है?

मुझे उसी विषय के बारे में another question मिला, लेकिन मुझे नहीं लगता कि यह मेरी संतुष्टि के लिए मेरे प्रश्न का उत्तर देता है।

कोई कहता है कि कोई आदेश परिभाषित नहीं किया गया है। लेकिन जैसा कि कोई और कहता है, यह ऑर्डर एक सरणी को पार करता है (0 से लंबाई -1 तक)। 8.8.4 The foreach statement

यह भी कहा गया था कि आदेश के साथ किसी मानक वर्ग के लिए यह समान है (उदा। List<T>)। मुझे इसे वापस करने के लिए कोई दस्तावेज नहीं मिल रहा है। इसलिए मुझे पता है कि यह अब इस तरह काम कर सकता है, लेकिन शायद अगले .NET संस्करण में यह अलग होगा (भले ही यह असंभव हो)।

मैंने भाग्य के बिना List(t).Enumerator दस्तावेज भी देखा है।

Another related question कहा गया है कि जावा के लिए, यह विशेष रूप से दस्तावेज में उल्लेख किया गया है:।

List.iterator() उचित अनुक्रम में इस सूची में तत्वों पर एक इटरेटर रिटर्न "

मैं देख रहा हूँ सी # दस्तावेज में ऐसा कुछ।

अग्रिम धन्यवाद।

संपादित करें: आपके सभी उत्तरों के लिए आप सभी के लिए धन्यवाद (आश्चर्यजनक है कि मुझे कितने तेज़ जवाब मिले)। मैं सभी उत्तरों से क्या समझता हूं कि List<T> हमेशा इसके अनुक्रमण के क्रम में पुनरावृत्त होता है। लेकिन मैं अभी भी Java documentation on List के समान, दस्तावेज की एक स्पष्ट शांति देखना चाहता हूं।

उत्तर

72

मूल रूप से यह IEnumerator कार्यान्वयन पर निर्भर है - लेकिन एक List<T> के लिए यह हमेशा सूची के प्राकृतिक क्रम में जाना होगा, इंडेक्सर रूप में एक ही क्रम अर्थात्: list[0], list[1], list[2] आदि

मैं डॉन ' टी मानते हैं कि यह स्पष्ट रूप से प्रलेखित है - कम से कम, मुझे ऐसे दस्तावेज नहीं मिला है - लेकिन मुझे लगता है कि आप इसे गारंटी के रूप में देख सकते हैं। उस क्रम में कोई भी बदलाव निर्बाध रूप से सभी प्रकार के कोड तोड़ देगा। असल में, मैं IList<T> के किसी भी कार्यान्वयन को देखकर आश्चर्यचकित हूं, जिसने इसका उल्लंघन नहीं किया। माना जाता है कि यह विशेष रूप से दस्तावेज देखना अच्छा लगेगा ...

+0

मैं सचमुच सिर्फ 5 सेकंड पहले एक जवाब के लिए जाँच की, और के बारे में कुछ इसी तरह पोस्ट करने के लिए था बदलने के लिए LINQ का उपयोग करना। तुम बहुत तेज हो! –

+0

आपके उत्तरों के लिए धन्यवाद। क्या कुछ दस्तावेज हैं जो इसकी गारंटी देता है? –

+0

एक IList के लिए आप निश्चित रूप से उस मानक कार्यान्वयन का बेहतर पालन करते हैं। कुछ संग्रहों के लिए संग्रह में वस्तुओं की एक स्पष्ट क्रम नहीं है, इसलिए इसे अलग-अलग कार्यान्वित किया जा सकता है। –

1

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

यदि आपका प्रोग्राम ऑर्डरिंग पर निर्भर करता है, तो आप सूची को घुमाने से पहले इसे सॉर्ट करना चाहेंगे।

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

3

ऑर्डर को फ़ोरैच लूप का उपयोग करके डेटा के संग्रह को पार करने के लिए उपयोग किए जाने वाले इटरेटर द्वारा परिभाषित किया गया है।

यदि आप एक मानक संग्रह का उपयोग कर रहे हैं जो सूचकांक (जैसे एक सूची) है, तो यह सूचकांक 0 से शुरू होने वाले संग्रह को आगे बढ़ाएगा और आगे बढ़ेगा।

यदि आपको ऑर्डरिंग को नियंत्रित करने की आवश्यकता है तो आप या तो नियंत्रित कर सकते हैं कि संग्रह के पुनरावृत्ति को implementing your own IEnumerable द्वारा कैसे नियंत्रित किया जाता है, या आप फोरच लूप को निष्पादित करने से पहले सूची को सॉर्ट कर सकते हैं।

यह बताता है कि कैसे Enumerator जेनेरिक सूची के लिए काम करता है। सबसे पहले वर्तमान तत्व अपरिभाषित है और अगले आइटम पर जाने के लिए MoveNext का उपयोग करता है।

यदि आप MoveNext पढ़ते हैं तो यह इंगित करता है कि यह संग्रह के पहले तत्व से शुरू होगा और जब तक यह संग्रह के अंत तक नहीं पहुंच जाता तब तक अगले स्थान पर जाएं।

+0

उत्तर और अतिरिक्त के लिए धन्यवाद (हर कोई इतनी तेज़ी से जवाब दे रहा है, मैं मुश्किल से रह सकता हूं)। मैंने भी इसे पढ़ा। हो सकता है कि मैं सिर्फ एक ऐसा शब्द निर्दिष्ट कर रहा हूं जो बहुत सटीक होना चाहता है>, लेकिन मुझे लगता है कि जब वे "पहला तत्व" कहते हैं तो उनका मतलब है कि पहला तत्व जिसे पुनरावृत्त किया जा रहा है, न कि तत्व जो पहले है पुनरावृत्त वर्ग के आदेश के लिए। –

+0

ठीक है अगर यह महत्वपूर्ण है कि आप निश्चित हैं कि यह जिस तरह से आप उम्मीद करते हैं, वही तरीका है जो मैंने कहा और आईनेमेरेबल को लागू करने का सबसे अच्छा तरीका है। –

8

अपने लिंक में, C# Language Specification Version 3.0, page 240 में स्वीकार किए जाते हैं जवाब कहता है:

जिस क्रम में foreach एक सरणी के तत्वों को पार करता, के रूप में है इस प्रकार है: एक आयामी सरणी के लिए तत्वों को बढ़ाने में आगे बढ़ते जाते हैं सूचकांक आदेश, सूचकांक 0 और सूचकांक की लंबाई के साथ समाप्त होने के साथ शुरू - 1. बहुआयामी सरणियों के लिए, तत्व इस तरह आगे बढ़ते जाते हैं कि दायीं आयाम के सूचकांकों पहले बढ़ रहे हैं, फिर अगला बायां आयाम, और इसी तरह बाईं ओर। निम्नलिखित उदाहरण एक दो आयामी सरणी में प्रत्येक मान बाहर प्रिंट, तत्व में आदेश:

using System; 
class Test 
{ 
    static void Main() { 
     double[,] values = { 
      {1.2, 2.3, 3.4, 4.5}, 
      {5.6, 6.7, 7.8, 8.9} 
     }; 
     foreach (double elementValue in values) 
      Console.Write("{0} ", elementValue); 
     Console.WriteLine(); 
    } 
} 

इस प्रकार उत्पादन उत्पादन किया जाता है के रूप में: 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 उदाहरण में

int[] numbers = { 1, 3, 5, 7, 9 }; 
foreach (var n in numbers) Console.WriteLine(n); 
the type of n is inferred to be int, the element type of numbers. 
+2

हां, लेकिन यह एक सरणी के लिए है। क्या यह स्वचालित रूप से सूची कक्षा के लिए भी है? –

+2

सूची अपने बैकिंग स्टोर के लिए एक सरणी का उपयोग करता है। तो हाँ। –

+8

लेकिन यह एक कार्यान्वयन विस्तार है। सूची * बैकिंग स्टोर के रूप में सरणी का उपयोग करने के लिए * आवश्यक * नहीं है। –

1

मुझे बस कोड की त्वरित हैक के समान कुछ करना पड़ा है, हालांकि यह मेरे लिए सूची को पुन: व्यवस्थित करने के लिए काम करने की कोशिश नहीं कर रहा था, हालांकि यह काम नहीं करता था।

आदेश

  DataGridViewColumn[] gridColumns = new DataGridViewColumn[dataGridView1.Columns.Count]; 
     dataGridView1.Columns.CopyTo(gridColumns, 0); //This created a list of columns 

     gridColumns = (from n in gridColumns 
         orderby n.DisplayIndex descending 
         select n).ToArray(); //This then changed the order based on the displayindex 
+0

मुझे नहीं पता कि यह सवाल से कैसे संबंधित है। आपका कोड 'सूची' का भी उपयोग नहीं करता है। मुझे लगता है कि आपने "सूची" के साथ क्या मतलब गलत समझा। –

+0

इसके अलावा, आप 'कॉलम' की सामग्री को पहले 'ग्रिड कॉलम' पर क्यों कॉपी कर रहे हैं? मुझे लगता है कि आप यह भी कर सकते हैं: 'DataGridViewColumn [] gridColumns = dataGridView1.Columns.OrderByDescending (n => n.DisplayIndex)। ToArray(); ' –

+0

@MatthijsWessels सूची का उपयोग करने के लिए इसे बदलना मुश्किल नहीं होगा, अगर तुम चाहते हो। –

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