IEnumerable और Array, IList और List में क्या अंतर है?


91

बीच क्या अंतर है IEnumerableऔर Array?

बीच क्या अंतर है IListऔर List?

लगता है ये एक ही प्रकार्य हैं।

जवाबों:


101

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

ऐरे रैंडम एक्सेस (यानी आप इसमें इंडेक्स कर सकते हैं) के साथ एक निश्चित आकार का संग्रह है।

सूची एक चर-आकार संग्रह (यानी आप तत्वों को जोड़ सकते हैं और हटा सकते हैं) यादृच्छिक अभिगम के साथ।

IList एक इंटरफ़ेस है जो एब्सट्रैक्ट लिस्ट फ़ंक्शनलिटी (काउंट, ऐड, रिमूव, इंडेक्सर एक्सेस) को विभिन्न ठोस वर्गों जैसे कि लिस्ट, बाइंडिंगलिस्ट, ऑब्ज़र्वेबल कॉलेक्शन, आदि से दूर करता है।


2
स्वीकृत उत्तर के अनुसार यहां stackoverflow.com/questions/1826658/… । IEnumerable पर गणना लगभग एक ही बीक्युस है जिसे कॉल करने के लिए ICollection पर गणना करने की कोशिश की जाती है
— Karsten

15
हां और ना। यदि IEnumerable भी एक ICollection है, तो काउंट () एक्सटेंशन विधि की जांच करती है, और यदि है तो अपनी काउंट प्रॉपर्टी को कॉल करती है। यदि IEnumerable एक ICollection नहीं है , तो गणना () अनुक्रम पुनरावृत्ति करने के लिए वापस गिर जाता है। शायद मुझे कहना चाहिए कि " केवल IEnumerable का उपयोग करने वाले तत्वों को गिनना बहुत ही अक्षम है ," क्योंकि निश्चित रूप से IEnumerable की उपस्थिति आपको एक अधिक कुशल विधि का उपयोग करने से नहीं रोकती है यदि ऑब्जेक्ट में एक है, और LINQ ऑब्जेक्ट्स के विस्तार के लिए बिल्कुल सटीक है उस।
— itowlson

17

IEnumerable एक इंटरफ़ेस है जो आइटम्स के संग्रह के माध्यम से पुनरावृत्ति की अनुमति देता है (उदाहरण के लिए फ़ॉरच्यू कीवर्ड)।

एक सरणी एक .NET आंतरिक है। यह एक ही प्रकार के आइटम रखता है, लेकिन यह एक निश्चित आकार का है। एक बार जब आप एक्स तत्वों के साथ एक सरणी बनाते हैं, तो यह बढ़ या सिकुड़ नहीं सकता है।

IList एक सूची के लिए इंटरफ़ेस को परिभाषित करता है, और IEnumerable को भी लागू करता है।

सूची लागू करें IList इंटरफ़ेस; यह एक ठोस प्रकार की सूची है।

.NET सूचियों और सरणियों के बीच का अंतर यह है कि सूचियों में तत्व जोड़े जा सकते हैं - वे सभी आवश्यक वस्तुओं को रखने के लिए पर्याप्त बड़े हो जाते हैं। यह सूची एक सरणी में आंतरिक रूप से संग्रहीत करती है और, जब सरणी अब सभी तत्वों को रखने के लिए पर्याप्त बड़ी नहीं होती है, तो एक नया सरणी बनाया जाता है और आइटम को कॉपी किया जाता है।

IList और arrays दोनों IEnumerable को लागू करते हैं। यह है कि इंटरफेस कैसे काम करता है - कक्षाएं अनुबंध को लागू करती हैं और एक समान तरीके से व्यवहार करती हैं और इसी तरह से व्यवहार किया जा सकता है (आप जानते हैं कि वर्ग IEnumerable लागू करता है, आपको हॉव्स या व्हिस को जानने की आवश्यकता नहीं है)। मेरा सुझाव है कि आप इंटरफेस और आगे पढ़ें।


1
उन पाठकों के लिए इस टिप्पणी को जोड़ना, जो सभी उत्तर नहीं पढ़ते हैं: सरणियाँ और सूची <> दोनों लागू करें IList <> (सरणियाँ इसे बहुत स्पष्ट रूप से लागू करती हैं, संभवतः इसलिए कि कई सदस्य नोटस्प्रूएड अपवाद को फेंक देते हैं)। यह कहना अधिक सही है कि IList IEnumerable से विरासत में मिला है, यह कहने के बजाय कि वह इसे लागू करता है।
— phoog

9

IEnumerable और IList इंटरफेस हैं । एरे और सूची वर्ग हैं। ऐरे को लागू करता है। सूची लागू करें IList जो IEnumerable का विस्तार करता है।

संपादित करें: जैसा कि itowlson ने एक टिप्पणी में उल्लेख किया है, Array भी IList को लागू करता है।


न ही मैं! यदि आप सरणी पर IList.RemoveAt कॉल करना शुरू करते हैं, तो क्या होता है?
— मार्क सिम्पसन

यह एक NotSupportedException फेंकता है। (नोट IList.RemoveAt और इसी तरह के IList तरीकों को स्पष्ट रूप से एरे पर लागू किया गया है ताकि वे एक सामान्य ऐरे संदर्भ पर दिखाई न दें!)
— itowlson

1
@itowlson मेरा कहना है कि केवल System.Array (प्रति वर्ग एक वर्ग) IList लागू करता है, लेकिन T [] IList <T> लागू नहीं करता है। T [] इसके बजाय IEnumerable <T> को लागू करता है। मुझे लगता है कि ओपी ने
— सिस्टम के

6

एक IEnumerable संग्रह की पीढ़ी आलसी है। उदाहरण:

public IEnumerable<int> GetTwoInts()
{
  yield return 1;
  yield return 2;
}
public void Something()
{
  var twoInts = GetTwoInts();
}

विधि में GetTwoInts () के लिए कुछ कॉल वास्तव में विधि GetTwoInts में परिणाम नहीं होगा क्योंकि संलयन के बाद से कभी भी iterated नहीं है।


क्या आप इसे थोड़ा विस्तृत कर सकते हैं? मुझे यकीन नहीं है कि अगर मैंने इसे सही समझा। क्या आप बाद में कोड की एक पंक्ति दिखा सकते हैं जिसके परिणामस्वरूप वास्तव में उस पद्धति को निष्पादित किया जाएगा? धन्यवाद!
— पांव जूल

@paaone twoIntsएक foreachया कॉल में डाल दिया twoInts.ToList()।
— row1

2

IEnumerableएक सामान्य-प्रयोजन इंटरफ़ेस है जो कई वर्गों द्वारा उपयोग किया जाता है, जैसे कि Array, Listऔर Stringकिसी संग्रह पर किसी को पुनरावृत्त करने के लिए। मूल रूप से, यह वही है जो foreachकथन को चलाता है ।

IListआम तौर पर आप Listअंत उपयोगकर्ताओं के प्रकार के प्रकार को उजागर करते हैं । यह इंटरफ़ेस अंतर्निहित संग्रह के लिए यादृच्छिक पहुँच की अनुमति देता है।


2

अन्य उत्तरों को पूरक करने के लिए, ध्यान दें कि फ़ॉरच स्टेटमेंट निष्पादित करते समय और बीच में एक प्रदर्शन अंतर होता है ।IList<T>List<T>

ऐसा इसलिए है क्योंकि इसके द्वारा लौटाए गए इटरेटर ऑब्जेक्ट List<T>.GetEnumeratorएक वैल्यू-टाइप है जबकि एक द्वारा लौटाया गया IList<T>.GetEnumeratorएक रेफरेंस-टाइप है, और इस तरह एक मेमोरी एलोकेशन की जरूरत है (देखें सी # में वैल्यू टाइप की लिस्ट का एन्युमरेटर )।

मेरी राय में, IList<T>वैसे भी बहुत अच्छा इंटरफ़ेस नहीं है। उदाहरण के लिए कॉल Addकर सकते हैं फेंक (देखें क्यों सरणी औजार IList? )। यदि आपको इनकैप्सुलेशन की आवश्यकता है, तो आप का उपयोग करना बेहतर होगा IEnumerable<T>या IReadOnlyList<T>।


1

अन्य उत्तरों के अलावा, LINQ का उपयोग करते समय Enumerable vs List / Array के बीच के अंतर को समझने से भारी प्रदर्शन पर असर पड़ सकता है। संक्षेप में, Enumerable को क्वेरी बिल्डर के रूप में माना जा सकता है जबकि List / Array क्वेरी का परिणाम है।

EntityFramework का उपयोग करके LINQ से SQL के संदर्भ में, पूर्व सिर्फ SQL क्वेरी को डेटाबेस के खिलाफ निष्पादित किए बिना बना रहा है और न ही बाद में विपरीत होने पर किसी भी डेटा को मेमोरी में लोड करने के लिए। इसलिए हम .ToList()तब तक कॉल करना स्थगित कर देंगे जब तक कि हमें व्यावसायिक तर्क करने के लिए मेमोरी में इसकी आवश्यकता न हो।

अन्य संदर्भ में, IEQ पर चलने वाले LINQ एक्सप्रेशन को तब तक क्रियान्वित किया जाएगा, जब तक .ToList()कि कॉल नहीं किया जाता। नीचे दिए गए उदाहरण पर विचार करें:

void Main()
{
    var w1 = "AB".AsEnumerable();
    Console.WriteLine($"W1: 1");
    w1 = w1.Where(W1);
    Console.WriteLine($"W1: 2");
    w1 = w1.Where(W2);
    Console.WriteLine($"W1: 3");
    w1.ToList();    
    Console.WriteLine($"----------");

    var w2 = "CD".AsEnumerable();
    Console.WriteLine($"W2: 1");
    w2 = w2.Where(W1);
    Console.WriteLine($"W2: 2");
    w2 = w2.ToList();
    Console.WriteLine($"W2: 3");
    w2 = w2.Where(W2);
    Console.WriteLine($"W2: 4");
    w2.ToList();    
    Console.WriteLine($"----------");
}

bool W1(char arg)
{
    Console.WriteLine($"W1:{arg}");
    return true;
}

bool W2(char arg)
{
    Console.WriteLine($"W2:{arg}");
    return true;
}

OUTPUT:
W1: 1
W1: 2
W1: 3
W1:A
W2:A
W1:B
W2:B
----------
W2: 1
W2: 2
W1:C
W1:D
W2: 3
W2: 4
W2:C
W2:D
----------

पहले उदाहरण में, दो .Where()को "संलग्न" किया जा रहा है और अंत में एक साथ निष्पादित किया .ToList()जाता है जब आइटम " ए " को पहले पाइप के माध्यम से जाना जाता है तो आइटम " बी ", इसलिए आउटपुट में " एएबीबी " को देखते हुए, जबकि दूसरे उदाहरण में, .Where()हर बार निष्पादित किया जाता है अगर हम फोन .ToList()तुरंत बाद, इसलिए देखकर " सीडी " और फिर " सीडी " फिर से, उत्पादन में दो बार। इसलिए, हर बार एक एनुमरबल को एक सूची में बदल दिया जाता है या संग्रह में सभी वस्तुओं पर एक ओ (एन) पुनरावृत्ति का खर्च आएगा , जो संग्रह के बड़े होने पर प्रदर्शन प्रभाव होगा।

हालांकि हम इस तरह से .ToList()LINQ कॉल के बीच कॉलिंग कोड लिखने की प्रवृत्ति नहीं रखते हैं, लेकिन यह तब अधिक बार होता है जब हम कोड को पुन: प्रयोज्य तरीकों में डालते हैं जो कि List/Arrayबजाय लौटते हैं IEnumerable।

हालांकि इसका मतलब यह नहीं है कि हमें हमेशा काम करना चाहिए IEnumerable। जैसा कि टॉवलसन ने उल्लेख किया है , कि इस तरह के संचालन के रूप .Count()में संग्रह पर पुनरावृत्ति का कारण होगा जबकि एक सूची या सरणी में यह जानकारी पूर्व-गणना की जाएगी और इसलिए List/Arrayयदि आप .Count()कई बार कॉल करने की योजना बनाते हैं तो यह अधिक कुशल होगा । ऐसा इसलिए भी है क्योंकि इसे गिनने के लिए .Countएक .Count()विधि के बजाय एक सूची पर एक संपत्ति है।


0

यह एक पुरानी पोस्ट है, लेकिन फिर भी जवाब देने के बारे में सोचा। IEnumerable एक व्यवहार है जबकि Array एक डेटा संरचना है (नियत आकार वाले तत्वों का संचित संग्रह, अनुक्रमित तत्वों तक पहुँचने की सुविधा)। जब एक ऐरे IEnumerable को लागू करता है, तो यह IEnumerable निहित संपत्ति (संग्रह पर पुनरावृत्ति की सुविधा के लिए) को चित्रित करने वाला है।

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