2009-03-25 9 views
8

कल्पना कीजिए कि मेरे पास एक सर्च सर्विस सर्विस है जिसमें एक निश्चित स्ट्रिंग से शुरू होने वाली सभी कारों को खोजने का एक तरीका है;मेरी सेवा किस इंटरफ़ेस को वापस करनी चाहिए? IQueryable, IList, IENumerable?

public static class Searcher{ 
    public IAnInterface<Car> CarsStartingWith(string startWith){ 
     //magic 
    } 
} 

मेरी सेवा का उपयोग किस इंटरफ़ेस का उपयोग करना चाहिए?
IQueryable मेरे शेष एप्लिकेशन में एक अच्छा तरल इंटरफेस के लिए प्रस्तुत कर सकता है।
आईनेमेरेबल के पास आलसी पहलू है जिसके साथ चल रहा है।
IList सिर्फ सबसे व्यावहारिक है।

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

+0

यहां लगभग डुप्लिकेट चर्चा: http://stackoverflow.com/questions/396513/should-parameters-returns-of-collections-be-ienumerablet-or-t –

उत्तर

2

यदि आप अपनी सभी सेवाओं को एक ही इंटरफेस वापस करने के लिए चाहते हैं तो मैं शायद IEnumerable<> के लिए जाऊंगा।

यह आसान पर्याप्त हो जाएगा अपने कॉल IQueryable में कन्वर्ट करने के लिए या एक List बनाने के लिए, यदि आवश्यक हो तो: जब तक आप एक गंभीर कारण नहीं करने के लिए है

IEnumerable<Car> cars = Searcher.CarsStartingWith("L"); 
var carsList = cars.ToList(); 
var queryableCars = cars.AsQueryable(); 
+0

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

+0

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

+4

'IENumerable ' लौटने के साथ समस्या यह है कि यदि आप तय करते हैं कि आप इसे 'IQuerable ' में परिवर्तित करना चाहते हैं, तो आप अब डीबी के खिलाफ पूछताछ नहीं कर रहे हैं, लेकिन स्मृति में वस्तुओं के खिलाफ। जैसा कि जेम्स कुरान ने इंगित किया कि 'IQueryable' थोड़ा भारी है, लेकिन अधिकांश परिदृश्यों में, मुझे एक क्वेरीबल सेट बैक की पेशकश करना बेहतर लगता है, उपभोक्ता को यह तय करने दें कि क्या वे इसे आईन्यूमेरेबल में डालना चाहते हैं। –

3

मैं IEnumerable का चयन करेंगे, क्योंकि यह ढांचे में एक अधिक केंद्रीय स्थान है, उन की जरूरत है कि के लिए बहुमुखी प्रतिभा उपलब्ध कराने, जबकि यह भी अपनेपन प्रदान उन लोगों के लिए जो अभी तक LINQ जैसी चीजों में फंस गए हैं।

+0

मुझे आईनेमरेबल पसंद है, अगर केवल देने का कोई तरीका था यह एक गिनती विधि है। मुझे पता है कि यह आलसी होने का निहित है कि यह नहीं पता कि कितने हैं, लेकिन गणना संपत्ति केवल कुछ है जो आपको कई बार चाहिए! –

+0

LINQ IENumerable के लिए एक गणना विस्तार विधि प्रदान करता है। –

+0

@ जेफ एक अच्छा विचार नहीं है कि मूल एक IQueryable था (इसे पुनर्प्राप्त और गणना की जाएगी)। – eglasius

2

IQueryable पर इसकी भारी आवश्यकता होगी - उदाहरण के लिए, आप एक सरणी वापस नहीं कर सके।

आमतौर पर मेरे लिए, IEnumerable या IList के बीच विकल्प आमतौर पर मानक मामले में लागू करने के लिए आसान हो रहा है।

+0

अभी तक मेरे लिए वही है। लेकिन मैं अपनी प्रोग्रामिंग शैली में थोड़ा और संगत बनने की कोशिश कर रहा हूं। और मैंने सोचा कि मैं IQueryable फेंक दूंगा क्योंकि तरल पदार्थ इंटरफेस आमतौर पर बहुत पठनीय दिखते हैं। –

2

संक्षिप्त उत्तर: यह निर्भर करता है।

लंबा उत्तर: अपने ग्राहक कोड की आवश्यकता होने वाले सबसे अमीर प्रकार को लौटाएं। यदि आपको आलसी लोडिंग की आवश्यकता नहीं है तो अधिकांश मामलों में IList काम करता है। आप अभी भी एक आईएलआईस्ट या आईनेमेरेबल के खिलाफ पूछने के लिए लिंक का उपयोग कर सकते हैं। यदि आलसी लोडिंग एक आवश्यकता है, तो IENumerable या IQueryable के साथ जाएं।

साइड नोट: सभी सेवाओं के लिए एक ही इंटरफेस लौटने पर एक महान लक्ष्य की तरह लग सकता है लेकिन विभिन्न ग्राहक उपयोग पैटर्न दिए गए हैं, तो आप विभिन्न इंटरफेस वापस कर सकते हैं।

+0

सच है, शायद आलसी/गैर आलसी के आधार पर एक नामकरण सम्मेलन दिलचस्प हो सकता है। –

+0

मैं दूसरी तरफ बहस करता हूं। IList IENumerable से अधिक तरीका प्रदान करता है और इसलिए आपको आलसी मूल्यांकन के बावजूद IENumerable चुनना चाहिए, जब तक कि आपको अतिरिक्त विधियों जैसे जोड़ने, निकालने और अनुक्रमणित करने की आवश्यकता न हो। –

2

हमेशा IEnumerable साथ जाना। इसके बाद आप yield return के साथ गेटर लागू कर सकते हैं।

IQueryable मछली का एक बिल्कुल अलग केतली है। ऐसा कुछ नहीं जिसे आप सामान्य रूप से एक सामान्य इन-मेमोरी कंटेनर के विकल्प के रूप में कार्यान्वित करेंगे।

बाकी में, IEnumerable और अन्य के बीच एक बड़ा अंतर है: यह पढ़ा गया है।

+0

आईन्यूमेरेबल को रिटर्न वैल्यू कास्ट करना इसे पढ़ा नहीं जाता है: इसे फिर से कॉल किया जा सकता है। यदि आप केवल पढ़ने के लिए चाहते हैं, तो परिणाम को रीडोनली संग्रह में लपेटें (उदाहरण के लिए सूची (टी) का उपयोग करना। केवल पढ़ने के पहले) इसे वापस करने से पहले। मैं आमतौर पर आईलीस्ट (टी) या आईसीओलेक्शन (टी) लौटाता हूं क्योंकि कॉलर्स अक्सर गिनती चाहते हैं। – Joe

+1

बेशक - मेरा मतलब है कि यह स्थाई रूप से टाइप किया गया है ताकि इसे पढ़ा जा सके। आप यह भी कह सकते हैं "फ़ील्ड को निजी बनाने का कोई मतलब नहीं है - वे वैसे भी उन्हें पाने के लिए प्रतिबिंब का उपयोग कर सकते हैं"। –

3

अंगूठे का मेरा नियम इस प्रकार है:

यदि कभी एक मौका है कि मैं नियमित की कोर एल्गोरिथ्म लेने के लिए और एक तरीका है कि मैं उपज रिटर्न का उपयोग कर सकते में यह refactor कर सकते हैं है, मैं IEnumerable < टी के साथ जाना होगा >।

उदाहरण के लिए, मेरे वर्तमान कार्यान्वयन किसी सरणी या एक सूची < टी का उपयोग करता है, तो > आंतरिक रूप से, लेकिन मुझे पता है कि, कम से कम सैद्धांतिक रूप से, मैं करना चाहते हैं और वह आंतरिक रूप से दोबारा काम आलसी मूल्यांकन करने के लिए करने में सक्षम हो सकता है, मैं हूँ एक आईनेमेरेबल < टी > वापस करें।

मुझे पता चला है कि IENumerable < टी > लौटने का लाभ निश्चित रूप से इसका उपयोग करने की परेशानी के लायक है।

हालांकि, अगर एल्गोरिदम, अपनी प्रकृति में, लौटने से पहले परिणामों का पूरी तरह से मूल्यांकन करने की आवश्यकता होगी (दुर्लभ है, लेकिन ऐसा होता है), मैं एक IList < टी > के साथ जाऊंगा। असल में, अगर मैं इसे पहले ही कंप्यूटिंग कर रहा हूं, तो मैं इसे वापस कर दूंगा। IList < टी > IENumerable < टी > लागू करता है, इसलिए सभी LINQ- संबंधित उपयोग के मामले अभी भी काम करते हैं, लेकिन आप आलसी मूल्यांकन खो देते हैं। अगर मुझे पहले से ही मूल्यांकन करने के लिए मजबूर किया गया है, तो यह कोई समस्या नहीं है।

मैं शायद ही कभी IQueryable लौटाता हूं। एकमात्र बार जब मैं इस इंटरफ़ेस का उपयोग करता हूं तो यह है कि अगर मैं सीधे एक क्वेरी करने योग्य डेटा एक्सेस लेयर, या कुछ समान बना रहा हूं। इसका उपयोग करने का उपर, ज्यादातर मामलों में, लाभ के लायक नहीं है।

हालांकि, यदि आपका लक्ष्य हमेशा एक इंटरफ़ेस का उपयोग करना है (मैं इस लक्ष्य से सहमत नहीं हूं), तो मैं IENumerable < टी > पर चिपके रहूंगा।

0

यदि आप वापसी प्रकार के रूप में IQueryable का उपयोग कर रहे हैं, तो आपके पास रिसाव अबास्ट्रक्शन के साथ एक सेवा परत है।

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