2012-05-02 13 views
32

मुझे ऑर्डरIEnumerable (या IEnumerable<T> में कोई फर्क नहीं पड़ता) के बारे में कोई प्रश्न है। , कि एक पर एक अनुसार क्रमबद्ध संग्रह संचालित करने के लिए की जरूरत हैआईनेमरेबल और ऑर्डर

while (enumerable.HasNext()) 
{ 
    object obj = enumerable.Current; 
    ... 
} 

अब, मान लें:

हम जानते हैं, IEnumerable के माध्यम से पुनरावृत्ति छद्म कोड निम्नलिखित तरीके से लिखा जा सकता है। क्या इस मामले में IENumerable का उपयोग किया जा सकता है या क्या इंडेक्सेशन समर्थन के साथ अन्य साधनों (यानी IList) का प्रयास करना बेहतर है?

दूसरे शब्दों में: IEnumerable का अनुबंध सामान्य रूप से आदेश के बारे में कोई गारंटी देता है?

यूपीडी: तो, IEnumerable ऑर्डर करने की गारंटी देने वाले सामान्य इंटरफ़ेस के लिए उचित माध्यम नहीं है। नया सवाल यह है कि इंटरफ़ेस या कक्षा ऑर्डर के साथ एक अपरिवर्तनीय संग्रह के लिए उपयोग किया जाना चाहिए? ReadonlyCollection? IList? उनमें से दोनों में Add() विधि है (यहां तक ​​कि पूर्व में भी लागू नहीं किया गया है।) कोई सुझाव?

पीएस मेरे अपने विचार: IEnumerable आदेश के बारे में कोई गारंटी नहीं प्रदान करता है। सही कार्यान्वयन अलग-अलग समीकरणों में अलग-अलग क्रम में समान तत्वों को वापस कर सकता है (एक SQL क्वेरी पर विचार करें)

पी.पी.एस. मुझे LINQ First() से अवगत है, लेकिन यदि IEnumerable इसके आदेश के बारे में कोई शब्द नहीं कहता है, तो यह एक्सटेंशन बहुत बेकार है।

उत्तर

25

IEnumerable/IEnumerable<T> आदेश देने के बारे में कोई गारंटी नहीं देता है, लेकिन IEnumerable/IEnumerable<T> का उपयोग करने वाले कार्यान्वयन आदेश की गारंटी दे सकते हैं या नहीं।

उदाहरण के लिए, यदि आप List<T> गणना, आदेश की गारंटी है, लेकिन अगर आप HashSet<T> गणना इस तरह की कोई गारंटी नहीं प्रदान की जाती है, फिर भी दोनों IEnumerable<T> इंटरफ़ेस उपयोग करते हुए स्पष्ट कर दिया जाएगा।

+1

एक और उदाहरण 'शब्दकोश <,>' है। यह स्पष्ट रूप से दस्तावेज किया गया है कि जिस क्रम में उसकी प्रविष्टियों की गणना की गई है वह अनिर्धारित है। तो कोड 'dict.Last()। कुंजी' (जहां 'dict'' शब्द <,> 'और' अंतिम() 'LINQ एक्सटेंशन विधि है) कोई कोड नहीं है। (मैंने एक डेवलपर को ठीक से ऐसा करने के बारे में सुना है।) –

+1

मैं पहले से ही कहूंगा कि यह समझना महत्वपूर्ण है कि कुछ सामान्य संग्रह के लिए आदेश के बारे में क्या गारंटी है। तो ऑर्डर गारंटी किसी विशेष क्रम के बारे में नहीं है (कहें, सॉर्टिंग के परिणामस्वरूप), लेकिन गारंटी के बारे में कि उसी संग्रह के तत्वों का क्रम बाद की गणनाओं के लिए समान है। अधिकांश संग्रह स्पष्ट रूप से इसकी गारंटी नहीं देते हैं। IList केवल एक प्रकार का शब्दकोश प्रस्तुत करता है जहां कुंजी इंडेक्स हैं। –

+0

IOrderedEumerable यह मानने के लिए एक संकेत हो सकता है कि संग्रह ऑर्डर की गारंटी देता है (हालांकि इंटरफ़ेस अभी भी नहीं करता है), लेकिन इसकी आवश्यकता से अधिक है - यह आमतौर पर एक विशेष सॉर्ट ऑर्डर का प्रतिनिधित्व करता है, जबकि हमें किसी भी (यादृच्छिक) ऑर्डर की आवश्यकता होती है जो कि बस है गणना के बीच गारंटी। निष्कर्ष निकालने के लिए, केवल ठोस कार्यान्वयन वास्तव में आदेश की गारंटी दे सकता है (उदा। ऐरे, सूची )। –

12

कार्यान्वयन विवरण। IENumerable आइटम की गणना करेगा - यह कैसे लागू किया गया है कार्यान्वयन के लिए है। अधिकांश सूचियां आदि उनके प्राकृतिक क्रम (इंडेक्स 0 ऊपर की ओर इत्यादि) के साथ चलती हैं।

क्या आईनेमरेबल का अनुबंध हमें सामान्य मामले में कुछ आदेश की गारंटी देता है?

नहीं, यह केवल गणना (प्रत्येक आइटम एक बार इत्यादि) की गारंटी देता है। IENumerable की कोई गारंटीकृत आदेश नहीं है क्योंकि यह अनियंत्रित वस्तुओं पर भी प्रयोग योग्य है।

मुझे LINQ फर्स्ट() के बारे में पता है, लेकिन यदि IENumerable इसके आदेश के बारे में कोई शब्द नहीं कहता है, तो यह एक्सटेंशन बल्कि बेकार है।

नहीं, ऐसा नहीं है, क्योंकि आपके पास आंतरिक आदेश हो सकता है। आप उदाहरण के रूप में एसक्यूएल देते हैं - परिणाम एक आईनेमरेबल है, लेकिन अगर मैंने पहले ऑर्डर किया है (ऑर्डरबी() का उपयोग करके) तो आईएनयूमेरेबल को LINQ की प्रति परिभाषा का आदेश दिया जाता है। AsNumerable()। पहला() मुझे ऑर्डर द्वारा पहले आइटम मिलता है।

4

आप दो अंक मिश्रण करते हैं: गणना और क्रमबद्ध करना।

जब आप IENumerable पर गणना करते हैं तो आपको आदेश की परवाह नहीं करनी चाहिए। आप इंटरफ़ेस के साथ काम करते हैं, और इसके कार्यान्वयन को ऑर्डर के बारे में ध्यान रखना चाहिए।

उदाहरण के लिए:

void Enumerate(IEnumerable sequence) 
{ 
    // loop 
} 

SortedList<T> sortedList = ... 
Enumerate (sortedList); 

विधि यह अभी भी निश्चित क्रम के साथ एक सूची है, लेकिन विधि विशेष इंटरफ़ेस कार्यान्वयन के बारे में पता नहीं है और यह विशेष लक्षण है अंदर।

6

शायद आप IOrderedEnumerable इंटरफ़ेस की तलाश में हैं? इसे OrderBy() जैसे एक्सटेंशन विधियों द्वारा वापस किया जाता है और ThenBy() के साथ बाद में सॉर्टिंग की अनुमति देता है।

+0

दुर्भाग्यवश यह काम नहीं करेगा यदि आप आईएलिस्ट जैसे इंटरफेस स्वीकार करना चाहते हैं जो ऑर्डर की गारंटी देता है लेकिन IOrderedEnumerable से प्राप्त नहीं होता है। Http://stackoverflow.com/q/5429974/1157054 देखें – Ajedi32

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