ICollection का उपयोग क्यों करें और IEnumerable या List <T> के कई-कई / एक-कई रिश्तों पर नहीं?


359

मैं इसे ट्यूटोरियल में बहुत अधिक देखता हूं, जैसे कि नेविगेशन गुण ICollection<T>

क्या एंटिटी फ्रेमवर्क के लिए यह एक अनिवार्य आवश्यकता है? क्या मैं उपयोग कर सकता हूं IEnumerable?

ICollectionइसके बजाय IEnumerableया यहाँ तक कि उपयोग करने का मुख्य उद्देश्य क्या है List<T>?

जवाबों:


439

आमतौर पर आप जो चुनते हैं वह इस बात पर निर्भर करेगा कि आपको किन तरीकों की आवश्यकता है। सामान्य रूप से - IEnumerable<>(MSDN: http://msdn.microsoft.com/en-us/library/system.collections.ienumerable.aspx ) उन वस्तुओं की सूची के लिए जिन्हें केवल इसके माध्यम से पुनरावृत्त करने की आवश्यकता होती है, ICollection<>(MSDN) http: // msdn.microsoft.com/en-us/library/92t2ye13.aspx ) उन वस्तुओं की सूची के लिए जिन्हें इसके माध्यम से पुनरावृत्त और संशोधित List<>करने की आवश्यकता है, उन वस्तुओं की सूची के लिए जिनके माध्यम से पुनरावृत्त, संशोधित, क्रमबद्ध, आदि की आवश्यकता है (यहां देखें पूरी सूची के लिए: http://msdn.microsoft.com/en-us/library/6sh2ey19.aspx )।

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

एक नेविगेशन प्रॉपर्टी जो रिश्ते के "कई" अंत का प्रतिनिधित्व करती है, उसे एक प्रकार का रिटर्न देना होगा जो ICollection को लागू करता है, जहां T रिश्ते के दूसरे छोर पर ऑब्जेक्ट का प्रकार है। - POCO परदे के पीछे MSDN बनाने के लिए आवश्यकताएँ

संबंधों को परिभाषित करने और प्रबंधित करने के बारे में अधिक जानकारी MSDN


2
तो, उसके साथ, Listबहुत बेहतर होना चाहिए, हाँ?
Jan Carlo Viray

3
@JanCarloViray - मैं Listबहुत उपयोग करता हूं । यद्यपि इसमें सबसे अधिक उपरि है लेकिन यह सबसे अधिक कार्यक्षमता प्रदान करता है।
ट्रैविस जे

1
सूचियों को उनके छांटने की क्षमता की तुलना में उनके अनुक्रमणकों द्वारा अधिक परिभाषित किया गया है (पूर्णांक अनुक्रमणिका होने से कुछ छांटना आसान हो जाता है, लेकिन इसकी आवश्यकता नहीं है)।
फोज

2
आपके संपादन के संबंध में, किसी संपत्ति को इंटरफ़ेस प्रकार तक सीमित करना स्मृति के बारे में नहीं है, बल्कि इनकैप्सुलेशन के बारे में है। विचार करें: private IEnumerable<int> _integers = new List<int> { 1, 2, 3 };उसी स्मृति का उपयोग करता है जैसेprivate List<int> _integers = new List<int> { 1, 2, 3 };
phoog

13
@TravisJ: List<T>की एक GetEnumerator()विधि है IEnumerable<T>, जिसके कार्यान्वयन से अलग , जो एक परिवर्तनशील संरचना प्रकार लौटाता है List<T>.Enumerator। अधिकांश संदर्भों में, उस प्रकार से एक स्टैंडअलोन हीप ऑब्जेक्ट की तुलना में थोड़ा बेहतर प्रदर्शन होगा। कंपाइलर जो डक-टाइप एन्युमेरेटर्स (जैसा कि C # और vb.net करते हैं) दोनों foreachकोड जनरेट करते समय इसका फायदा उठा सकते हैं । यदि पहले के List<T>लिए डाली जाती IEnumrable<T>है foreach, तो IEnumerable<T>.GetEnumerator()विधि ढेर-आवंटित वस्तु लौटाएगा, अनुकूलन को असंभव बना देगा।
सुपरकैट

85

ICollection<T>उपयोग किया जाता है क्योंकि IEnumerable<T>इंटरफ़ेस आइटम जोड़ने, आइटम हटाने, या अन्यथा संग्रह को संशोधित करने का कोई तरीका प्रदान नहीं करता है।


3
सूची <T> के खिलाफ तुलना करने के बारे में क्या?
जन कार्लो विरय

12
List<T>लागू होता है ICollection<T>
स्पेंडर

गैर-जेनेरिक ICollectionकिसी भी तरह से आइटम जोड़ने की अनुमति नहीं देता है, लेकिन यह अभी भी एक उपयोगी सहायक है IEnumerable<T>क्योंकि यह एक Countसदस्य प्रदान करता है जो आमतौर पर हर चीज की गणना करने की तुलना में बहुत तेज है। ध्यान दें कि यदि a IList<Cat>या किसी ICollection<Cat>कोड की अपेक्षा करते हुए पास किया गया है IEnumerable<Animal>, Count()तो गैर-जेनेरिक को लागू करने पर एक्सटेंशन मेथड तेज होगा ICollection, लेकिन यह नहीं कि यदि यह केवल जेनरिक इंटरफेस को लागू करता है, क्योंकि एक टिपिकल ICollection<Cat>लागू नहीं होगा ICollection<Animal>
सुपरकैट

58

आपके प्रश्न के बारे में जवाब List<T>:

List<T>एक वर्ग है; एक इंटरफ़ेस निर्दिष्ट करने से कार्यान्वयन के अधिक लचीलेपन की अनुमति मिलती है। एक बेहतर सवाल "क्यों नहीं है IList<T>?"

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


21

ICollection और IEnumerable के बीच कुछ मूल अंतर हैं

  • IEnumerable - Enumerator प्राप्त करने के लिए केवल GetEnumerator विधि शामिल है और लूपिंग की अनुमति देता है
  • ICollection में अतिरिक्त विधियाँ हैं: Add, Remove, Contains, Count, CopyTo
  • ICollection को IEnumerable से विरासत में मिला है
  • ICollection के साथ आप जोड़ / हटाने जैसी विधियों का उपयोग करके संग्रह को संशोधित कर सकते हैं। आपके पास IEnumerable के साथ ऐसा करने की स्वतंत्रता नहीं है।

सरल कार्यक्रम:

using System;
using System.Collections;
using System.Collections.Generic;

namespace StackDemo
{
    class Program 
    {
        static void Main(string[] args)
        {
            List<Person> persons = new List<Person>();
            persons.Add(new Person("John",30));
            persons.Add(new Person("Jack", 27));

            ICollection<Person> personCollection = persons;
            IEnumerable<Person> personEnumeration = persons;

            // IEnumeration
            // IEnumration Contains only GetEnumerator method to get Enumerator and make a looping
            foreach (Person p in personEnumeration)
            {                                   
               Console.WriteLine("Name:{0}, Age:{1}", p.Name, p.Age);
            }

            // ICollection
            // ICollection Add/Remove/Contains/Count/CopyTo
            // ICollection is inherited from IEnumerable
            personCollection.Add(new Person("Tim", 10));

            foreach (Person p in personCollection)
            {
                Console.WriteLine("Name:{0}, Age:{1}", p.Name, p.Age);        
            }
            Console.ReadLine();

        }
    }

    class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public Person(string name, int age)
        {
            this.Name = name;
            this.Age = age;
        }
    }
}

13

मुझे यह इस तरह याद है:

  1. IEnumerable में एक विधि GetEnumerator () है जो एक संग्रह में मूल्यों के माध्यम से पढ़ने की अनुमति देता है, लेकिन इसे नहीं लिखता है। सी # में प्रत्येक कथन के लिए एन्यूमरेटर का उपयोग करने की सबसे अधिक जटिलता हमारे लिए ध्यान में रखी गई है। IEnumerable के पास एक संपत्ति है: वर्तमान, जो वर्तमान तत्व देता है।

  2. ICollection IEnumerable को लागू करता है और कुछ अतिरिक्त गुणों को जोड़ता है जिनमें से सबसे अधिक उपयोग काउंट है। ICollection का सामान्य संस्करण Add () और Remove () विधियों को लागू करता है।

  3. IList IEnumerable और ICollection दोनों को लागू करता है, और पूर्णांक अनुक्रमण को आइटमों में जोड़ता है (जो आमतौर पर आवश्यक नहीं है, जैसा कि डेटाबेस में आदेश दिया जाता है)।


4
आपके द्वारा लिखे गए ICollection और IList के आधार पर समान हैं। कृपया जोड़ें कि IList में क्या जोड़ा गया है जो ICollection में मौजूद नहीं है।
बेट

ICollection VS IList, IList- सिस्टम में केवल इंटरफ़ेस। कोलोनियन जिसमें IEnumerable और ICollection और अतिरिक्त कार्यक्षमता की सभी कार्यक्षमता शामिल है। IList में इन्सर्ट और रिमूव तरीके हैं। दोनों विधियां अपने पैरामीटर में सूचकांक को स्वीकार करती हैं। तो, यह संग्रह पर सूचकांक आधारित संचालन का समर्थन करता है।
ई। मीर

7

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


14
TIL जो ICollectionकेवल पढ़ने के लिए है, जबकि ICollection<T>ऐसा नहीं है।
कार्ल जी

2

नेविगेशन गुणों को आमतौर पर आभासी के रूप में परिभाषित किया जाता है ताकि वे कुछ एंटिटी फ्रेमवर्क कार्यक्षमता जैसे आलसी लोडिंग का लाभ उठा सकें।

यदि एक नेविगेशन संपत्ति कई संस्थाओं (जैसे कई-से-कई या एक-से-कई रिश्तों में) को धारण कर सकती है, तो इसका प्रकार एक सूची होना चाहिए जिसमें प्रविष्टियों को जोड़ा, हटाया और अद्यतन किया जा सकता है, जैसे कि ICollection।

https://www.asp.net/mvc/overview/getting-started/getting-started-with-ef-using-mvc/creating-an-entity-framework-data-model-for-an-asp-net- MVC-आवेदन


2

मैंने अतीत में जो भी किया है, वह मेरे आंतरिक वर्ग के संग्रह का उपयोग करके घोषित किया है IList<Class>, ICollection<Class>या IEnumerable<Class>(यदि स्थिर सूची) इस बात पर निर्भर करता है कि मुझे अपनी रिपॉजिटरी में एक विधि में निम्नलिखित में से कितनी भी संख्या करनी होगी: enumerate, sort / ऑर्डर या संशोधित । जब मुझे बस वस्तुओं पर गणना (और शायद क्रमबद्ध) करने की आवश्यकता होती है तो मैं List<Class>एक IEnumerable पद्धति के भीतर संग्रह के साथ काम करने के लिए एक अस्थायी बनाता हूं । मुझे लगता है कि यह अभ्यास केवल तभी प्रभावी होगा जब संग्रह अपेक्षाकृत छोटा हो, लेकिन यह सामान्य रूप से अच्छा अभ्यास हो सकता है। कृपया मुझे सही करें अगर इस बात का सबूत है कि यह अच्छा अभ्यास क्यों नहीं होगा।


0

तर्क के साथ / साथ बॉक्स के बाहर सोचने की कोशिश करें और अपने प्रश्न में इन तीन इंटरफेस को स्पष्ट रूप से समझें:

जब कुछ उदाहरणों का वर्ग System.Collection.IEnumerable इंटरफ़ेस को लागू करता है, तब सरल शब्दों में, हम कह सकते हैं कि यह उदाहरण, दोनों ही शब्द हैं, जो कि असंख्य और चलने योग्य हैं, जिसका अर्थ है कि यह उदाहरण किसी भी लूप में जाने / पास / पास होने की अनुमति देता है traverse / iterate सभी वस्तुओं और तत्वों के माध्यम से / जिसमें यह उदाहरण है।

इसका मतलब यह है कि यह उन सभी वस्तुओं और तत्वों की गणना करना भी संभव है जो इस उदाहरण में हैं।

प्रत्येक वर्ग जो System.Collection.IEnumerable इंटरफ़ेस को लागू करता है, वह GetEnumerator विधि को लागू करता है जो कोई तर्क नहीं लेता है और एक System.Collections.IEnumerator उदाहरण देता है।

System.Collections.IEnumerator इंटरफ़ेस का उदाहरण C ++ पुनरावृत्तियों के समान है।

जब कुछ उदाहरणों का वर्ग System.Collection.ICollection इंटरफ़ेस को सरल शब्दों में लागू करता है, तो हम कह सकते हैं कि यह उदाहरण कुछ चीजों का संग्रह है।

इस इंटरफ़ेस का सामान्य संस्करण, अर्थात् System.Collection.Generic.ICollection, अधिक जानकारीपूर्ण है क्योंकि यह सामान्य इंटरफ़ेस स्पष्ट रूप से बताता है कि संग्रह में किस प्रकार की चीज़ें हैं।

यह सब उचित, तर्कसंगत, तार्किक है और समझ में आता है कि System.Collections.ICollection Interface को System.Collections.IEnumerable इंटरफ़ेस से विरासत में मिला है, क्योंकि सैद्धांतिक रूप से हर संग्रह भी असंख्य और चलने योग्य दोनों है और यह सैद्धांतिक रूप से सभी वस्तुओं और तत्वों पर जाने के लिए संभव है। हर संग्रह में।

System.Collections.ICollection इंटरफ़ेस एक परिमित गतिशील संग्रह का प्रतिनिधित्व करता है जो परिवर्तनशील होते हैं, जिसका अर्थ है कि मौजूद आइटम को संग्रह से हटाया जा सकता है और नए आइटम को उसी संग्रह में जोड़ा जा सकता है।

यह बताता है कि क्यों System.Collections.ICollection इंटरफ़ेस में "जोड़ें" और "निकालें" विधियाँ हैं।

क्योंकि System.Collections.ICollection इंटरफ़ेस के उदाहरणों में परिमित संग्रह हैं तो "परिमित" शब्द का अर्थ है कि इस इंटरफ़ेस के प्रत्येक संग्रह में हमेशा एक सीमित संख्या में आइटम और तत्व होते हैं।

System.Collections.ICollection इंटरफ़ेस की संपत्ति गणना इस संख्या को वापस करने के लिए मानती है।

System.Collections.IEnumerable इंटरफ़ेस में ये विधियाँ और गुण नहीं हैं जो System.Collections.ICollection इंटरफ़ेस है, क्योंकि इसका कोई मतलब नहीं है कि System.Collections.IEnumerable में ये विधियाँ और गुण होंगे जो System.Collections.ICollection इंटरफ़ेस के पास है।

लॉजिक यह भी कहता है कि हर उदाहरण जो कि दोनों के लिए पर्याप्त और चलने योग्य है, जरूरी नहीं कि एक संग्रह है और जरूरी नहीं कि परिवर्तनशील हो।

जब मैं परिवर्तनशील कहता हूं, तो मेरा मतलब है कि तुरंत यह मत सोचिए कि आप किसी ऐसी चीज से कुछ जोड़ या हटा सकते हैं, जो कि असंख्य और चलने योग्य हो।

अगर मैंने सिर्फ प्राइम नंबरों का कुछ परिमित अनुक्रम बनाया है, उदाहरण के लिए, प्राइम नंबरों का यह परिमित अनुक्रम वास्तव में System.Collections.IEnumerable इंटरफ़ेस का एक उदाहरण है, क्योंकि अब मैं एक ही लूप में इस परिमित अनुक्रम में सभी प्रमुख संख्याओं पर जा सकता हूं और मैं उनमें से प्रत्येक के साथ जो करना चाहता हूं, जैसे कि उनमें से प्रत्येक को कंसोल विंडो या स्क्रीन पर प्रिंट करना है, लेकिन प्राइम नंबर का यह परिमित क्रम System.Collections.ICollection इंटरफ़ेस का उदाहरण नहीं है, क्योंकि इससे कोई मतलब नहीं है अभाज्य संख्याओं के इस परिमित अनुक्रम में संयुक्त संख्याएँ जोड़ें।

इसके अलावा, आप अगले पुनरावृत्ति में वर्तमान प्राइम नंबर के लिए निकटतम निकटतम बड़ा प्राइम नंबर प्राप्त करना चाहते हैं, यदि आप भी प्राइम नंबरों के इस परिमित अनुक्रम से मौजूद प्राइम नंबरों को हटाना नहीं चाहते हैं।

इसके अलावा, आप सिस्टम के GetEnumerator विधि में "यील्ड रिटर्न" का उपयोग, कोड और लिखना चाहते हैं। प्राइम नंबर का उत्पादन करने और मेमोरी हीप पर कुछ भी आवंटित न करने और फिर दोनों के लिए गारबेज कलेक्टर (GC) को आवंटित करने के लिए। निपटाएं और इस मेमोरी को ढेर से मुक्त करें, क्योंकि यह स्पष्ट रूप से ऑपरेटिंग सिस्टम मेमोरी की बर्बादी है और प्रदर्शन को कम करता है।

सिस्टम पर विधियों और गुणों का आह्वान करते समय हीप पर डायनेमिक मेमोरी आबंटन और डिक्लोकेशन किया जाना चाहिए। सिस्टम का चयन। लेकिन सिस्टम के तरीकों और गुणों को लागू करते समय नहीं ।Collections.IEnumerer Interface (हालांकि System.Collections.IEnumerable इंटरफ़ेस केवल है। 1 विधि और 0 गुण)।

इस स्टैक ओवरफ्लो वेबपेज में दूसरों ने जो कहा है, उसके अनुसार, System.Collections.IList इंटरफ़ेस केवल एक ऑर्डर करने योग्य संग्रह का प्रतिनिधित्व करता है और यह बताता है कि System.Collections.IList इंटरफ़ेस के तरीके System.Collections.ICollection इंटरफ़ेस के विपरीत इंडेक्स के साथ काम क्यों करते हैं।

संक्षेप में System.Collections.ICollection इंटरफ़ेस का यह अर्थ नहीं है कि इसका एक उदाहरण क्रमबद्ध है, लेकिन System.Collections.IList इंटरफ़ेस इसका अर्थ है।

सैद्धांतिक रूप से आदेश दिया सेट अनियंत्रित सेट का विशेष मामला है।

यह भी समझ में आता है और बताता है कि क्यों System.Collections.IList इंटरफ़ेस इनहेरिट करता है System.Collections.ICollection इंटरफ़ेस।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.