2014-10-10 12 views
7

मेरे लिए, IEnumerable<T> सी # (अच्छी तरह से, .NET) में डेटा के मनमानी सेट को इंगित करता है जिसे पुनरावृत्त किया जा सकता है। इसे किसी भी चीज़ द्वारा समर्थित किया जा सकता है, जैसे SELECT क्वेरी, किसी सरणी की सामग्री, कंसोल में उपयोगकर्ता द्वारा टाइप किए गए वर्ण, या पीआई के अंक। डेटा को इंडेक्स द्वारा संदर्भित नहीं किया जा सकता है, यह आवश्यक रूप से परिमित या अनंत नहीं है, न ही इसे संशोधित किया जा सकता है। यादृच्छिक संख्याओं के IEnumerable<double> की तरह, बाद में समान रूप से कॉल किए जाने पर यह डेटा का एक अलग सेट भी हो सकता है। यह उपभोक्ता को foreach लूप जैसे उत्पादित आंकड़ों की बिट्स है।क्या ऑर्डर प्रासंगिकता IENumerable <T> के साथ निहित है या यह स्पष्ट होना चाहिए?

अब किसी अन्य चीज़ में एक अवधारणा पर विचार करें जो डेटा सेट से संबंधित है: एसक्यूएल। एसक्यूएल में, पंक्तियों का क्रम स्पष्ट रूप से निर्दिष्ट होने तक गारंटी नहीं है और प्रासंगिक नहीं है। उदाहरण के लिए, यदि आप SELECT * FROM stack_overflow_posts LIMIT 1 करते हैं, तो डेटाबेस द्वारा कोई निहितार्थ नहीं किया गया है कि जिस पंक्ति को आप वापस प्राप्त करते हैं वह वास्तव में पहली पंक्ति है जो डाली गई थी, न ही सबसे पुरानी पंक्ति। उदाहरण के लिए, आपको ORDER BY posted_date_time के साथ परिणामों को स्पष्ट रूप से ऑर्डर करने की आवश्यकता है।

क्या यह वही अवधारणा IEnumerable<T> के साथ .NET में गणनाओं पर लागू होती है? IEnumerable<T> का उपयोग एक प्रभाव है कि परिणाम हमेशा एक विशेष क्रम में पैदा किया जाएगा? उदाहरणों में मैंने पहले दिए गए उदाहरणों में, मैं हाँ कहूंगा, आदेश लागू किया जाएगा, क्योंकि यदि वे एक अलग क्रम में गणना की गई थी, तो परिणाम व्यर्थ होंगे; यदि आपको वास्तविक कुंजीस्ट्रोक की तुलना में कंसोल में उपयोगकर्ता द्वारा टाइप किए गए वर्ण मिलते हैं, तो उन्हें पढ़ने का क्या मतलब है? स्पष्ट रूप से LINQ के पास OrderBy() परिणाम देने के लिए परिणाम हैं, लेकिन यह स्पष्ट आदेश है, अंतर्निहित नहीं है।

एक इंटरफ़ेस को लागू करने वाला एक वर्ग प्रभावी रूप से इंटरफ़ेस द्वारा परिभाषित विधियों को लागू न करने के लिए एक विशेष पैटर्न का पालन करने का वादा कर रहा है। IEnumerable<T> का अर्थ है कि इसका डेटा किसी प्रासंगिक क्रम में प्रस्तुत किया जाएगा, या क्या यह गणना करने के लिए गणना के उपभोक्ताओं तक स्पष्ट रूप से आदेश देने के लिए है? यदि मेरे पास ऐसी विधि है जो आइटम को एक अनिर्धारित क्रम में उत्पन्न करती है - या बल्कि, एक आदेश जो उपभोक्ताओं के लिए प्रासंगिक नहीं है और किसी भी बिंदु पर परिवर्तन के अधीन है - क्या मुझे IEnumerable<T> के अलावा कुछ और उपयोग करना चाहिए?

उत्तर

10

IEnumerable<T> का उपयोग यह एक संकेत है कि परिणाम हमेशा एक विशेष क्रम में उत्पन्न किया जाएगा?

सं। IEnumerable बस गारंटी देता है कि ऑब्जेक्ट को फिर से चालू किया जा सकता है। तथ्य यह है कि List<T>, उदाहरण के लिए, सूचकांक के अनुसार हमेशा आरोही क्रम में आइटम आउटपुट करता है List<T> विशेष रूप से एक कार्यान्वयन विवरण है।

एक इंटरफ़ेस को लागू करने वाला एक वर्ग प्रभावी रूप से इंटरफ़ेस द्वारा परिभाषित विधियों को लागू न करने के लिए एक विशेष पैटर्न का पालन करने का वादा करता है। IEnumerable<T> का अर्थ है कि इसका डेटा किसी प्रासंगिक क्रम में प्रस्तुत किया जाएगा, या क्या यह गणना करने के लिए गणना के उपभोक्ताओं तक स्पष्ट रूप से आदेश देने के लिए है?

नहीं, IEnumerable लागू करने से कोई ऑर्डर नहीं मिलता है। IEnumerable पर ऑब्जेक्ट का उपभोग करते समय, आपको स्पष्ट रूप से ऑर्डर देना होगा यदि आप गारंटी देना चाहते हैं कि आपका डेटा हर बार एक ही क्रम में बाहर आने वाला है।

यदि आप सीएलआर संग्रह प्रकारों के बारे में सोचते हैं जो IEnumerable को लागू करते हैं, तो यह सीधा है। कल्पना कीजिए कि आपने एक विधि बनाई है जो IEnumerable<string> लौटा दी है।यह विधि List<string> लौटा सकती है, जिसका कार्यान्वयन IEnumerable पर एक निश्चित आदेश है, लेकिन यह आसानी से HashSet<string> लौटा सकता है, जिसके लिए एक आदेश समझ में नहीं आता है।

अगर मैं एक विधि है कि एक अपरिभाषित क्रम में आइटम पैदावार है - या बल्कि, यह है कि उपभोक्ताओं के लिए प्रासंगिक नहीं है और किसी भी बिंदु पर परिवर्तन के अधीन है एक आदेश - मैं IEnumerable<T> के अलावा कुछ इस्तेमाल करना चाहिए?

मैं कहूंगा कि IEnumerable<T> आपकी आवश्यकताओं को अच्छी तरह से उपयुक्त बनाता है। अतिरिक्त स्पष्ट होने के लिए, आप अपनी विधि को दस्तावेज कर सकते हैं और बता सकते हैं कि परिणाम में वस्तुओं का क्रम अपरिभाषित है और कॉल से कॉल में बदल सकता है।

+5

मैं जोड़ता हूं कि ['IOrderedEnumerable '] (http://msdn.microsoft.com/en-ca/library/vstudio/bb534852 (v = vs.100) .aspx) आदेशित मामले के लिए है । ('ऑर्डर बी 'इसे वापस करता है) – Vache

7

IEnumerable<T> क्रम लेकिन implementer, या IEnumerable<T>सकता है गारंटी आदेश लौटने विधि की गारंटी नहीं देता है। उदाहरण के लिए, File.ReadLines आपको क्रम में फ़ाइल लाइन देने की गारंटी है। Enumerable.Whereकी गारंटी है आदेश को सुरक्षित रखें। हालांकि, जैसा कि आपने बताया है, आप आसानी से एक विधि लिख सकते हैं जो हर बार एक नया GUID उत्पन्न करता है, और उसके पास कोई ऑर्डर नहीं होगा।

+3

+1, मुझे स्पष्टीकरण पसंद है कि एक विधि * लौटने *' IENumerable ' वास्तव में निर्दिष्ट कर सकता है कि वापस आने वाले गणना के लिए कुछ आदेश है –

1

IEnumerable<T> की एक दुर्भाग्यपूर्ण सीमा है, जबकि वहाँ कई विशेषताएं जो अधिकांश प्रयोगों है कर रहे हैं, और कुछ उपभोक्ताओं भरोसा पर, कोई साधन है जिसके द्वारा वस्तुओं का संकेत कर सकते वे इस तरह के लक्षण है या नहीं।

इन विशेषताओं के अलावा तथ्य यह है कि यदि एक विधि एक IEnumerable<T> कॉल GetEnumerator और संग्रह की सामग्री के माध्यम से दोहराता प्राप्त करना, यह MoveNext कॉल की एक सीमित संख्या के बाद अंत तक पहुंच जाएगा है; यदि यह GetEnumerator को पास किए गए IEnumerable<T> के साथ कुछ और किए बिना दोबारा कॉल करता है, तो उसे उसी क्रम में आइटम्स का एक ही अनुक्रम प्राप्त करना चाहिए और उसी बिंदु पर समाप्त होना चाहिए।

ध्यान दें कि उपर्युक्त वास्तव में कई अलग-अलग मानदंडों को शामिल करता है; ऐसे कई कार्यान्वयन हैं जो सभी को मिलते हैं, लेकिन लगभग किसी भी संयोजन को पूरा करने के लिए कार्यान्वयन के लिए यह संभव है। उपरोक्त कथन से अलग मानदंडों में से:

  1. कि एक गणना एक सीमित संख्या में वस्तुओं का उत्पादन करेगी।

  2. कि कई समीकरण हमेशा समान संख्या में आइटम उत्पन्न करेंगे।

  3. एक ही अनुक्रम में दिखाई देने वाली सभी वस्तुओं को एक ही अनुक्रम में दिखाई देगा।

यदि कोई गणना आइटम की सीमित संख्या नहीं देती है, तो सवाल यह है कि एकाधिक पुनरावृत्तियों में समान संख्या उत्पन्न होती है या नहीं।

  • कई संग्रह, जब एक थ्रेड द्वारा ही प्रयोग किया जाता, निश्चित रूप से सभी का पालन करेंगे: एक तरफ से, तथापि, यह संभव IEnumerable<T> के एक कार्यान्वयन के लिए उपरोक्त मानदंडों के छह शेष संयोजनों में से किसी का पालन करने की है तीन।

  • एक "सत्य" यादृच्छिक जनरेटर किसी का भी पालन नहीं कर सकता है।

  • एक छद्म-यादृच्छिक जनरेटर केवल # 3 का पालन कर सकता है।

  • समवर्ती ऐड-ओनली सूची # 1 और # 3 का पालन कर सकती है।

  • कुछ अन्य समवर्ती संग्रह केवल # 1 का पालन कर सकते हैं।

  • समवर्ती कोड द्वारा उपयोग की जाने वाली एक सरणी केवल # 1 और # 2 का पालन कर सकती है।

कुछ तरीकों जो अगर पारित वस्तु कुछ या ऊपर उल्लिखित विशेषताओं के सभी का पालन करने में विफल रहता है एक IEnumerable<T> खराब हो सकता है प्राप्त है, विशेषताओं IEnumerable<T> अनुबंध का हिस्सा नहीं हैं, और न ही वहाँ एक IEnumerable<T> के लिए किसी भी तरह से है यह निर्दिष्ट करने के लिए कि यह कौन सा मानदंड पूरा कर सकता है। उम्मीद है कि कोड IEnumerable<T> को एक विधि में पास करने जा रहा है, यह जानने के लिए जिम्मेदार है कि IEnumerable<T> का "दयालु" क्या है, और यह तरीका जो बाहरी कोड से प्राप्त विधि में IEnumerable<T> पास करता है, किसी भी तरह से अपने उपभोक्ताओं को व्यक्त करना चाहिए उन विधियों की आवश्यकताएं जिनके लिए IEnumerable<T> उदाहरण पास किए गए हैं।

यदि IEnumerable<T> एक बार गणना की जाती है, तो यह कुछ अनुक्रमों में आइटम वापस कर देगी। अधिकांश IEnumerable<T> कार्यान्वयन के साथ, बार-बार गणनाएं समान अनुक्रम में वस्तुओं को उत्पन्न करती हैं, और कुछ कोड उस व्यवहार पर निर्भर करते हैं, लेकिन IEnumerable<T> अनुबंध में कुछ भी नहीं है जो निर्दिष्ट करता है।

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