2009-09-21 10 views
10

ठीक है, मुझे आशा है कि समुदाय बड़े पैमाने पर कार्यस्थल बहस को हल करने में हमारी सहायता करेगा जो थोड़ी देर के लिए चल रहा है। इसे इंटरफेस को परिभाषित करने के साथ करना है जो या तो किसी प्रकार की सूचियों को स्वीकार या वापस कर देता है। ऐसा करने के कई तरीके हैं:आप इंटरफेस के लिए कौन सा पसंद करते हैं: टी [], आईनेमेरेबल <T>, IList <T>, या अन्य?

public interface Foo 
{ 
    Bar[] Bars { get; } 
    IEnumerable<Bar> Bars { get; } 
    ICollection<Bar> Bars { get; } 
    IList<Bar> Bars { get; } 
} 

मेरा अपना वरीयता वापसी मूल्यों के लिए तर्क और सरणियों के लिए IEnumerable उपयोग करने के लिए है:

public interface Foo 
{ 
    void Do(IEnumerable<Bar> bars); 
    Bar[] Bars { get; } 
} 

इस दृष्टिकोण के लिए मेरे तर्क यह है कि कार्यान्वयन वर्ग एक बना सकते हैं सीधे आईनेमरेबल से सूचीबद्ध करें और बस इसे सूची.ToArray() के साथ वापस कर दें। हालांकि कुछ का मानना ​​है कि एक सरणी के बजाय IList वापस किया जाना चाहिए। मेरे पास यहां की समस्या यह है कि अब लौटने से पहले इसे पढ़ने के लिए इसे केवल पढ़ने की आवश्यकता है। IENumerable लौटने का विकल्प क्लाइंट कोड के लिए परेशानी प्रतीत होता है?

आप क्या उपयोग करते हैं/पसंद करते हैं? (विशेष रूप से पुस्तकालयों के संबंध में जो आपके संगठन के बाहर अन्य डेवलपर्स द्वारा उपयोग किए जाएंगे)

+1

मैंने अपने तरीकों की त्रुटियों को देखा है। नीचे दिए गए कई राज्यों के स्पष्ट डेवलपर्स टी [] गुणों को नहीं देखते हैं अपरिवर्तनीय। मुझे लगता है कि उनके दुरुपयोग ने मुझे कुछ बुरी आदतों को सिखाया है। अगर मैंने एक प्रतिलिपि बनाई है, तो मैंने सरणी को संशोधित नहीं किया है, हालांकि, मुझे लगता है कि यह पैदा हुआ भ्रम का एहसास हुआ है। आईनेमेरेबल एक हाथ से नीचे है मुझे लगता है कि विजेता। –

उत्तर

18

मेरी वरीयता IEnumerable<T> है। सुझाए गए इंटरफेस में से कोई अन्य उपभोक्ता को अंतर्निहित संग्रह को संशोधित करने की अनुमति देता है। यह लगभग निश्चित रूप से नहीं है कि आप क्या करना चाहते हैं क्योंकि यह उपभोक्ताओं को एक आंतरिक संग्रह को चुपचाप संशोधित करने की अनुमति दे रहा है।

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

+3

+1 किसी भी एप्लिकेशन में मैंने कम से कम 'आईन्यूमेरेबल' पर काम किया है, आपको केवल 9 8% समय चाहिए। –

+0

यह नहीं कह रहा कि आप गलत हैं, लेकिन ऐसा नहीं लगता कि आप नहीं हैं एक retuning केवल लिखित सूची या एक उथली प्रतिलिपि (या अन्यथा अपरिवर्तनीय बना रही है)? – annakata

+1

@annakata, लेकिन यह आपके उपभोक्ताओं को कैसे व्यक्त करें? आप केवल आईएलिस्ट कहने की वापसी को नहीं देख सकते हैं और जानते हैं: 1) क्या मुझे इसे संशोधित नहीं करना चाहिए, 2) संशोधन को फेंकने से अक्षम किया गया है (शब्दकोश :: मूल्य) या 3) एक पूर्ण प्रति वापस लौटाया जा रहा है। यह उपयोग से बस स्पष्ट नहीं है। दूसरी तरफ IENumerable लौटने पर काफी स्पष्ट रूप से "आप मेरे डेटा को छू रहे नहीं हैं" कहते हैं। – JaredPar

15

मैं सरणियों नहीं लौटते - अगर आप वास्तव में एक अस्थायी अनुक्रम IList<T> या ICollection<T> इंटरफ़ेस का उपयोग या एक ठोस Collection<T> लौटने के बजाय की जरूरत है - वे वास्तव में जब एक API बनाने का उपयोग करने के एक भयानक वापसी प्रकार हैं।

इसके अलावा, मैं सुझाव है कि आप एरिक Lippert द्वारा Arrays considered somewhat harmful पढ़ें:

मैं प्रोग्रामिंग भाषा के लेखक से एक नैतिक सवाल मिला पर मेरी राय है या नहीं, प्रोग्रामर शुरुआत का अनुरोध दूसरे दिन पाठ्यपुस्तकों सरणी का उपयोग करने के लिए सिखाया जाना चाहिए।

के बजाय वास्तव में जवाब देने कि सवाल है, मैं उसे सरणियों के बारे में मेरी राय , मैं कैसे सरणियों का उपयोग, हम कैसे उम्मीद सरणियों भविष्य में इस्तेमाल किया, और इतने पर होना करने के लिए की एक लंबी सूची दे दी है। यह थोड़ा लंबा हो जाता है, लेकिन पास्कल की तरह, मैं में इसे कम करने के लिए समय नहीं था।

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

+1

उस लिपर्ट लिंक को पहले नहीं पढ़ा था - उस अकेले के लिए +1 – annakata

+0

डिट्टो - अच्छा पढ़ा। –

+2

चिल्लाओ के लिए धन्यवाद। :) परिदृश्य के लिए उपयुक्त क्या है इसका उपयोग करने के लिए –

8

संपत्ति संग्रह अनुक्रमित रहे हैं (और सूचकांक आवश्यक अर्थ अर्थ है) के लिए, आप ReadOnlyCollection<T> का उपयोग करना चाहिए (रीड ओनली) या IList<T> (पठन/लेखन)। यह सबसे लचीला और अभिव्यक्तिपूर्ण है। गैर-अनुक्रमित संग्रहों के लिए, IEnumerable<T> (केवल पढ़ने के लिए) या ICollection<T> (पढ़ें/लिखें) का उपयोग करें।

विधि मानकों IEnumerable<T> का उपयोग करना चाहिए जब तक कि वे 1) 2) आवश्यक अर्थ प्रयोजनों (IList<T>) के लिए अनुक्रमित की आवश्यकता संग्रह (ICollection<T>) में जोड़ने के लिए/आइटम हटा जरूरत है या। यदि विधि उपलब्धता को अनुक्रमणित करने से लाभान्वित हो सकती है (जैसे सॉर्टिंग रूटीन), तो यह कार्यान्वयन में विफल होने पर हमेशा as IList<T> या .ToList() का उपयोग कर सकता है।

+0

+1 ... यह वास्तव में सभी को शासन करने के लिए 1 नहीं है ... ReadOnlyCollection बनाम Inumerable कहने का एक और तरीका प्री-लोड बनाम आलसी लोड किया गया है। – eglasius

1

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

1

मुझे लगता है इसके बारे में सबसे उपयोगी कोड लिखने के मामले में: कोड जो अधिक कर सकता है।

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

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

ध्यान दें कि मैं वापसी प्रकारों के संबंध में थोड़ा अपरंपरागत हूं। एक और सामान्य दृष्टिकोण एक विशिष्ट कार्यान्वयन में खुद को लॉक करने से बचने के लिए तरीकों से कमजोर प्रकारों को वापस करना है।

+1

... अगर मेरे पास पहले से कुछ है जो IList लागू करता है, तो मैं इसका भी उपयोग कर सकता हूं ... हाँ, मैं आपका बिंदु देखता हूं; हालांकि, यह अजीब साइड इफेक्ट्स का कारण बन सकता है। इसे कम से कम एक ReadOnlyCollection () में लपेटना चाहिए। –

+1

@csharptest।नेट अगर आप तर्क देते हैं कि एक IList को केवल पढ़ने के संग्रह में पैक किया जाना चाहिए, तो फिर आप अपने स्वयं को एक ऐरे क्यों वापस कर देंगे जो कि किसी भी तत्व को किसी भी प्रकार से प्रतिस्थापित किया जा सकता है, दिए गए प्रकार –

+0

पर निर्दिष्ट किसी भी चीज़ के साथ प्रतिस्थापित किया जा सकता है आप यहां सही हैं; मेरी गुमराह धारणा यह थी कि यह स्पष्ट होगा कि आपको एक प्रतिलिपि मिल रही थी और इसे संशोधित करने का कोई मतलब नहीं होगा। मैं मानता हूं कि मैं इस चर्चा से स्पष्ट रूप से गलत था ... यह मेरे लिए कभी नहीं हुआ कि लोग "फू। बार्स [0] = एक्स" या कुछ ऐसे बकवास करेंगे। वैसे भी मुझे प्रबुद्ध करने में मदद करने के लिए धन्यवाद :) –

0

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

लेकिन एक विशिष्ट डेटा का उपयोग टियर के लिए एक वापसी प्रकार के रूप में, एक गणना संपत्ति अक्सर उपयोगी है, और मैं एक गणना संपत्ति या संभवतः IList < टी> के साथ एक ICollection < टी> वापस जाने के लिए है, तो मुझे लगता है कि ठेठ उपभोक्ताओं होगा पसंद करेंगे एक सूचकांक का उपयोग करना चाहते हैं।

यह कॉलर के लिए एक संकेत भी है कि संग्रह वास्तव में भौतिकृत किया गया है। और इस प्रकार कॉलर डेटा एक्सेस स्तर से अपवाद प्राप्त किए बिना लौटे संग्रह के माध्यम से पुन: प्रयास कर सकता है। यह महत्वपूर्ण हो सकता है। उदाहरण के लिए, एक सेवा लौटा संग्रह से स्ट्रीम (उदा। एसओएपी) उत्पन्न कर सकती है। आलसी-मूल्यांकन किए गए पुनरावृत्ति के कारण धारा उत्पन्न करते समय डेटा एक्सेस लेयर से अपवाद फेंक दिया गया है, तो यह अजीब हो सकता है, क्योंकि अपवाद फेंकने पर आउटपुट स्ट्रीम पहले ही आंशिक रूप से लिखी जाती है।

0

चूंकि लिंक एक्सटेंशन विधियों को IENumerable < टी > में जोड़ा गया था, मुझे पता चला है कि अन्य इंटरफेस का मेरा उपयोग काफी कम हो गया है; शायद लगभग 80%। मैं सूची < टी > धार्मिक रूप से उपयोग करता था क्योंकि इसमें ऐसी विधियां थीं जो आलसी मूल्यांकन जैसे खोज, FindAll, ForEach और इसी तरह के प्रतिनिधियों को स्वीकार करती थीं। चूंकि यह System.Linq के एक्सटेंशन के माध्यम से उपलब्ध है, मैंने उन सभी संदर्भों को IENumerable < टी > संदर्भों के साथ बदल दिया है।

0

मैं सरणी के साथ नहीं जाऊंगा, यह एक प्रकार है जो संशोधन की अनुमति देता है अभी तक जोड़ने/निकालने नहीं है ... पैक के सबसे खराब की तरह।अगर मैं संशोधन की अनुमति देना चाहता हूं, तो मैं एक प्रकार का उपयोग करूंगा जो जोड़ने/निकालने का समर्थन करता है।

जब आप संशोधनों को रोकना चाहते हैं, तो आप इसे पहले ही लपेट रहे हैं/इसे कॉपी कर रहे हैं, इसलिए मुझे नहीं पता कि एक आईनेमरेबल या रीडऑनली कोलेक्शन के साथ क्या गलत है। मैं बाद में जाऊंगा ... कुछ जो मुझे आईनेमरेबल के बारे में पसंद नहीं है वह यह है कि प्रकृति द्वारा आलसी है, फिर भी जब आप इसे केवल लपेटने के लिए प्री-लोड किए गए डेटा के साथ उपयोग कर रहे हैं, तो कोड के साथ काम करने वाले कोड को प्री- लोड किया गया डेटा या अतिरिक्त "अनावश्यक" रेखाएं हैं :(... जो परिवर्तन के दौरान बदसूरत परिणाम प्राप्त कर सकते हैं।

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