2011-02-11 14 views
37

IEnumerable और IEnumerable<T> के बीच क्या अंतर है?आईनेमेरेबल और आईनेमेरेबल <T> के बीच अंतर?

मैंने इन दोनों इंटरफेस को लागू करने वाले कई ढांचे वर्गों को देखा है, इसलिए मैं जानना चाहता हूं कि दोनों को लागू करने से कौन से फायदे मिलते हैं?

कृपया एक नज़र कि वे किस तरह परिभाषित किया गया है है:

public interface IEnumerable 
{ 
    [DispId(-4)] 
    IEnumerator GetEnumerator(); 
} 
public interface IEnumerable<T> : IEnumerable 
{ 
    IEnumerator<T> GetEnumerator(); 
} 

हम देखते हैं के रूप में, IEnumerable<T>IEnumerable से निकला है, जिसका अर्थ है कि जो कुछ IEnumerable है, IEnumerable<T> इनहेरिट करती है, तो क्यों हम दोनों सिर्फ IEnumerable<T> के बजाय लागू करते हैं ? IEnumerable<T> लागू नहीं कर रहा है?

  • IList और IList<T>
  • ICollection और ICollection<T>

मैं इन के बारे में रूप में अच्छी तरह जानना चाहते हैं:

इसी तरह, अन्य इसी तरह के जोड़े हैं।

उत्तर

48

मूल रूप से एनओएनजी 1.0 और 1.1 में, मूल रूप से नोंगनेरिक इंटरफेस पहले आया था। फिर जब .NET 2.0 बाहर आया, जेनेरिक समकक्ष बाहर आए। मूल रूप से आप दोनों को लागू करने के है, और आप स्पष्ट इंटरफ़ेस का उपयोग करने के लिए है - जीवन बहुत आसान होता है, तो जेनरिक नेट 1.0 :)

में जगह बनायी को लागू करने के संदर्भ में "केवल" बजाय दोनों की IEnumerable<T> कार्यान्वयन भी, यह देखते हुए कि दोनों पैरामीटर रहित GetEnumerator विधि को परिभाषित करते हैं।

public IEnumerator<T> GetEnumerator() 
{ 
    // Return real iterator 
} 

// Explicit implementation of nongeneric interface 
IEnumerator IEnumerable.GetEnumerator() 
{ 
    // Delegate to the generic implementation 
    return GetEnumerator(); 
} 

दूसरी ओर, आप शायद ही कभी इन बातों को पूरी तरह से हाथ से, सौभाग्य से लागू करने की आवश्यकता (yield return आदि के साथ) सी # 2 में शुरू iterator ब्लॉक के साथ: IEnumerator<T> भी IEnumerator फैली रूप में, यह सामान्य रूप से कुछ इस तरह है। आपको उपरोक्त की तरह कुछ लिखने की आवश्यकता हो सकती है, और फिर GetEnumerator10 में yield return का उपयोग करें।

नोट IList<T> करता है कि नहीं विस्तार IList, और ICollection<T> करता नहीं विस्तार ICollection। ऐसा इसलिए है क्योंकि ऐसा करने के लिए यह कम प्रकार-सुरक्षित है ... जबकि किसी भी सामान्य इटरेटर को किसी संभावित मूल्य (संभावित मुक्केबाजी) के किसी भी मूल्य के object, IList और के मानों को में जोड़ने की अनुमति देने के कारण एक गैर-अनुवर्ती पुनरावर्तक के रूप में देखा जा सकता है। संग्रह; और IList<int> पर एक स्ट्रिंग जोड़ने (कहने) को समझ में नहीं आता है।

संपादित करें: हमें IEnumerable<T> की आवश्यकता क्यों है ताकि हम एक प्रकार के सुरक्षित तरीके से फिर से सक्रिय हो सकें और उस जानकारी को प्रचारित कर सकें। अगर मैं आपको IEnumerable<string> वापस लौटाता हूं, तो आप जानते हैं कि आप सुरक्षित रूप से यह मान सकते हैं कि इससे लौटाई गई सब कुछ एक स्ट्रिंग संदर्भ या शून्य होगी। IEnumerable के साथ, हमें प्रभावी ढंग से (foreach कथन में स्पष्ट रूप से डालना था) अनुक्रम से लौटाया गया प्रत्येक तत्व, क्योंकि CurrentIEnumerator की संपत्ति object की तरह है।क्यों हम अभी भीIEnumerable की आवश्यकता है - क्योंकि मूल रूप से पुराने इंटरफेस कभी नहीं जाते हैं। इसका उपयोग कर बहुत अधिक मौजूदा कोड है।

यह IEnumerable<T> के लिए संभव हो गया होता IEnumerable विस्तार करने के लिए नहीं है, लेकिन फिर किसी भी एक IEnumerable<T> का उपयोग करने के लिए इच्छुक कोड IEnumerable को स्वीकार करने के लिए एक विधि में कॉल नहीं कर सका - और कि .NET 1.1 से जैसे तरीकों का एक बहुत वहाँ थे और 1.0।

+12

+1 जेनिक्स ने इसे .NET 1.0 में बनाया था, तो जीवन बहुत आसान होता। ... – Oded

+0

@ जोन: सवाल यह है: हम पहले से ही 'आईनेमेरेबल ' लागू करने पर हमें 'आईनेमेरेबल' को लागू करने की आवश्यकता क्यों है। , या ठीक इसके विपरीत? – Nawaz

+0

@ नवाज: मैंने अपना जवाब संपादित कर लिया है। जेनेरिक एक अच्छी बात क्यों है इस विचार के साथ आप कितने सहज हैं? –

5

एक प्रकार वस्तु का एक उद्देश्य, अन्य रिटर्न प्रकार टी का एक उद्देश्य

2

के रूप में करने के लिए आप कक्षाएं, दोनों को परिभाषित करने के लिए पर्याप्त है, हालांकि IEnumerable < टी> लागू IEnumerable, इसकी जरूरत नहीं है, लेकिन अच्छा है क्यों देखते हैं रिटर्न कभी-कभी उप इंटरफेस को सूचीबद्ध करने के लिए एक स्वयं दस्तावेज़ में।

interface IA { } 
interface IB : IA { } 

class A : IB {} // legal, IB implements IA 

class B : IA, IB {} // also legal, possible more clear on intent 
1

लूप के माध्यम से पुनरावृत्ति करते समय IENumerator राज्य को बनाए रखता है। यह कर्सर की स्थिति को याद करता है और IENumerable नहीं करता है।

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