2012-01-05 9 views
18

नियम है कि a public APIs should never return a list, मैं सभी कोड है कि लौटे सूचियों परिवर्तित चकाचौंध कर रहा हूँ के बाद, ICollection<T> बजाय वापस जाने के लिए:क्या आईसीओलेक्शन <T> एक ऑर्डर है?

public IList<T> CommaSeparate(String value) {...} 

public ICollection<T> CommaSeparate(String value) {...} 

और हालांकि एक ICollection एक Count है, कोई हो जाता है उस सूचकांक द्वारा आइटम प्राप्त करने का तरीका।

और हालांकि एक ICollection एक प्रगणक (foreach अनुमति) को उजागर करता है, मैं कोई गारंटी नहीं देखते हैं कि गणना के आदेश, के रूप में "नीचे" के लिए विरोध सूची के "टॉप" पर शुरू होता है।

मैं ICollection का उपयोग न करके इस को कम कर सकता है, और बदले Collection का उपयोग करें:

public Collection<T> Commaseparate(String value) {...} 

यह एक Items[index] वाक्य रचना के उपयोग की अनुमति देता है।

दुर्भाग्यवश, मेरा आंतरिक कार्यान्वयन एक सरणी बनाता है; जो मैं IList या ICollection लौटने के लिए डाला जा सकता है, लेकिन Collection के रूप में नहीं।

संग्रह के आइटम तक पहुंचने का कोई तरीका है?

यह व्यापक सवाल भीख माँगता: क्या एक ICollection भी कोई ऐसा आदेश है?


वैचारिक रूप से, कल्पना मैं एक कमांड लाइन स्ट्रिंग पार्स करना चाहते हैं। यह महत्वपूर्ण है कि वस्तुओं का क्रम बनाए रखा जाए।

संकल्पनात्मक रूप से, मुझे एक अनुबंध की आवश्यकता है जो स्ट्रिंग टुपल्स के "आदेशित" सेट को इंगित करता है।

IEnumerable<String> Grob(string s) 

ICollection<String> Grob(string s) 

IList<String> Grob(string s) 

Collection<String> Grob(string s) 

List<String> Grob(string s) 
+3

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

+3

IOrderedEnumerable के बारे में क्या, LINQ ऑर्डर द्वारा वापस आती है? – Euphoric

उत्तर

9

ICollection<T> इंटरफ़ेस एक आदेश के बारे में कुछ भी निर्दिष्ट नहीं है: एक API अनुबंध के मामले में, आदेश, जो निम्न में से सही है इंगित करने के लिए। वस्तुएं ऑब्जेक्ट द्वारा निर्दिष्ट ऑर्डर में होंगी। उदाहरण के लिए, यदि आप ValuesSortedDictionary संग्रह संग्रह करते हैं, तो ऑब्जेक्ट्स शब्दकोश के तुलनात्मक द्वारा परिभाषित क्रम में होंगे।

यदि आपको अनुबंध के द्वारा वापस आने की विधि की आवश्यकता है, तो किस प्रकार के अनुबंध को एक निश्चित आदेश की आवश्यकता होती है, तो आपको अधिक विशिष्ट प्रकार को वापस कर विधि के हस्ताक्षर में व्यक्त करना चाहिए।

वस्तु के क्रम प्रकार की परवाह किए बिना लौट आए, व्यवहार पर विचार जब स्थिर संदर्भ IList<T> या ICollection<T> है: जब आप (एक foreach पाश में शायद परोक्ष) GetEnumerator() कहते हैं, आप एक ही विधि कॉल करने के लिए जा रहे हैं और संदर्भ के स्थिर प्रकार के बावजूद वही ऑब्जेक्ट प्राप्त करें। इसलिए CommaSeparate() विधि के रिटर्न प्रकार के बावजूद यह वही व्यवहार करेगा।

अतिरिक्त सोचा:

के रूप में किसी और ने कहा, FxCop नियम List<T>, नहीं IList<T> उपयोग करने के खिलाफ चेतावनी दी है; आपके द्वारा लिंक किया गया सवाल यह पूछ रहा है कि क्यों FXCop का उपयोग List<T> के स्थान पर करने की अनुशंसा नहीं करता है, जो एक और मामला है। अगर मुझे लगता है कि आप कमांड लाइन स्ट्रिंग को पार्स कर रहे हैं जहां ऑर्डर महत्वपूर्ण है, तो मैं IList<T> के साथ रहूंगा यदि मैं आप थे।

+0

मैं * वास्तव में * एक सरणी वापस नहीं कर रहा हूँ। मैं * मेरे * कार्यान्वयन में एक सरणी का उपयोग करने के लिए होता है; लेकिन यह एक कार्यान्वयन विस्तार है जिसे मैं छिपाना चाहता हूं, और भविष्य में बदलने की अनुमति दूंगा। –

+0

@IanBoyd समझा। अंतिम अनुच्छेद में सरणी के बारे में टिप्पणियां लागू होंगी इससे कोई फर्क नहीं पड़ता कि विधि से किस प्रकार का भुगतान किया जाता है। मैं स्पष्ट करने के लिए संपादित करेंगे। – phoog

+0

उत्कृष्ट, 'IList' तब है! –

4

ICollection उदाहरण में जो भी वर्ग लागू होता है उसका "ऑर्डर" होता है। यही है, List<T> को ICollection के रूप में संदर्भित करने से उसका ऑर्डर बिल्कुल भी नहीं बदलेगा।

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

तो, आपके सवाल का:

एक ICollection भी एक आदेश है?

उत्तर है: यह पूरी तरह से उस कक्षा पर निर्भर करता है जो इसे लागू करता है।

8

आईसीओलेक्शन में गारंटीकृत आदेश नहीं है, लेकिन वास्तव में यह वर्ग जो लागू करता है (या नहीं) हो सकता है।

यदि आप एक आदेशित संग्रह वापस करना चाहते हैं, तो IList<T> वापस लौटें और FxCop की आम तौर पर ध्वनि, लेकिन बहुत सामान्य, सलाह पर भी लटका न लें।

1

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

सभी आईसीलेक्शंस आईन्यूमेरेबल को लागू करते हैं, जो एक बार ऑर्डर करता है, आदेश दिया जाता है या अन्यथा।

संपादित करें: प्रश्न में कमांड लाइन पार्सिंग के बारे में आपके अतिरिक्त उदाहरण के जवाब में, मैं तर्क दूंगा कि उपयुक्त रिटर्न प्रकार उस तर्क पर निर्भर करता है कि आप बाद में उन तर्कों के साथ क्या कर रहे हैं, लेकिन आईन्यूमेरेबल शायद सही है।

मेरा तर्क यह है कि आईएलआईस्ट, आईसीओलेक्शन, और उनके ठोस कार्यान्वयन ग्रोब से लौटाई गई सूची में संशोधन की अनुमति देते हैं, जिसे आप शायद नहीं चाहते हैं। चूंकि .NET में अनुक्रमित अनुक्रम इंटरफ़ेस नहीं है, इसलिए आपके कॉलर्स को अजीब कुछ करने से रोकने के लिए आईन्यूमेरेबल सबसे अच्छा शर्त है, जैसे कि वे वापस आने वाली पैरामीटर सूची को संशोधित करने का प्रयास कर रहे हैं।

4

नहीं, आईसीओलेक्शन एक आदेश का संकेत नहीं देता है।

4

ICollection सिर्फ एक इंटरफ़ेस — ऑर्डर करने के बारे में कोई कार्यान्वयन या स्पष्ट विनिर्देश नहीं है। इसका मतलब है कि अगर आप किसी आदेशित तरीके से गणना करते हैं, जो आपके ICollection का उपभोग कर रहा है, तो आदेश दिया गया है।

ऑर्डर केवल अंतर्निहित, , ऑब्जेक्ट को लागू करने से निहित है। ICollection में कोई विनिर्देश नहीं है जो कहता है कि इसे आदेश दिया जाना चाहिए या नहीं। परिणामस्वरूप कई बार अंतर्निहित वस्तु अंतर्निहित वस्तु का आह्वान करेगा, जो एकमात्र ऐसा स्थान है जहां वे नियम निर्धारित किए जाएंगे। एक ऑब्जेक्ट उस तरीके को बदलता नहीं है जिसकी गणना इसकी जाती है क्योंकि यह इस इंटरफ़ेस को प्राप्त करता है।इंटरफ़ेस निर्दिष्ट था कि यह एक आदेश दिया गया परिणाम है, तो आप कार्यान्वयन ऑब्जेक्ट के आदेशित परिणाम पर सुरक्षित रूप से भरोसा कर सकते हैं।

+0

'आईसीओलेक्शन 'यह सिर्फ एक इंटरफ़ेस है, लेकिन यह व्यवहार के नियमों की भी घोषणा है। –

+0

बिल्कुल, लेकिन इंटरफ़ेस में कुछ भी नहीं है जो कहता है कि इसे आदेश दिया जाना चाहिए या अन्यथा। –

3

एक ICollection<T> सिर्फ एक इंटरफ़ेस है; चाहे वह आदेश दिया गया हो या नहीं, पूरी तरह से कार्यान्वित कार्यान्वयन पर निर्भर है (जिसे अपारदर्शी माना जाता है)।

यदि आप इसे इंडेक्स द्वारा एक्सेस करने में सक्षम होना चाहते हैं, तो आप IList<T> के रूप में चीजों को वापस करना चाहते हैं, जो IEnumerable<T> और ICollection<T> दोनों है। हालांकि, किसी को ध्यान में रखना चाहिए कि अंतर्निहित कार्यान्वयन के आधार पर, संग्रह में मनमाना आइटम प्राप्त करने के लिए औसत पर ओ (एन/2) समय की आवश्यकता हो सकती है।

मेरे झुकाव 'संग्रह' इंटरफेस पूरी तरह से बचने के लिए और बदले में समस्या डोमेन के मामले में संग्रह का प्रतिनिधित्व करने और उस प्रकार के लिए उपयुक्त उचित तार्किक संचालन उजागर एक कस्टम प्रकार का उपयोग किया जाएगा।

3

ICollection<T> में ऑर्डर हो सकता है, लेकिन वास्तविक ऑर्डरिंग इसे लागू करने वाले वर्ग पर निर्भर करता है। यह दिए गए इंडेक्स पर किसी आइटम के लिए accesor नहीं है। IList<T> इंडेक्स द्वारा एक्सेस प्रदान करने के लिए इस इंटरफ़ेस को माहिर हैं।

+0

यदि मैं दो बार 'आईसीओलेक्शन' को दोहराता हूं तो क्या मुझे दोनों बार एक ही ऑरर में आइटम मिलेंगे? –

+2

इसे लागू करने वाले वर्ग पर निर्भर करता है। इसकी गारंटी नहीं है। – Krizz

0

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

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