2010-09-15 13 views
27

क्यों इस एक संकलक त्रुटि उत्पन्न करता है:संग्रह प्रारंभकर्ता अभिव्यक्ति को IENumerable को कार्यान्वित करने की आवश्यकता क्यों होती है?

class X { public void Add(string str) { Console.WriteLine(str); } } 

static class Program 
{ 
    static void Main() 
    { 
     // error CS1922: Cannot initialize type 'X' with a collection initializer 
     // because it does not implement 'System.Collections.IEnumerable' 
     var x = new X { "string" }; 
    } 
} 

लेकिन यह नहीं करता है:

class X : IEnumerable 
{ 
    public void Add(string str) { Console.WriteLine(str); } 
    IEnumerator IEnumerable.GetEnumerator() 
    { 
     // Try to blow up horribly! 
     throw new NotImplementedException(); 
    } 
} 

static class Program 
{ 
    static void Main() 
    { 
     // prints “string” and doesn’t throw 
     var x = new X { "string" }; 
    } 
} 

संग्रह initializers प्रतिबंधित करने के लिए कारण क्या है - जो एक Add विधि के लिए एक कॉल के लिए वाक्यात्मक चीनी हैं - उन वर्गों के लिए जो एक इंटरफेस को कार्यान्वित करते हैं जो Add विधि है और जिसका उपयोग नहीं किया जाता है?

+4

सी # में कुछ चीजें हैं जो मुझे नहीं मिलती हैं। यह उनमें से एक है। एक और 'foreach' है। – leppie

+2

@leppie: आप foreach के बारे में "पाने" क्या नहीं है? –

+1

@ जोन स्कीट: मुझे लगता है कि लेप्पी इस तथ्य को संदर्भित करता है कि संकलक को एक विशिष्ट इंटरफ़ेस की आवश्यकता के बिना किसी विधि की उपस्थिति की आवश्यकता होती है जो दृढ़ता से टाइप की गई भाषा में बतख-टाइपिंग व्यवहार की तरह होती है। –

उत्तर

23

एक ऑब्जेक्ट प्रारंभकर्ता नहीं है; एक संग्रह प्रारंभकर्ता करता है। ऐसा इसलिए है कि यह कक्षाओं पर लागू होता है जो वास्तव में संग्रहित प्रतिनिधित्व करते हैं, बजाय मनमानी वाले जिनके पास Add विधि है। मुझे यह मानना ​​है कि हर बार मैंने IEnumerable स्पष्ट रूप से "कार्यान्वित" किया है, केवल संग्रह प्रारंभकर्ताओं को अनुमति देने के लिए - लेकिन से NotImplementedException फेंक दिया।

ध्यान दें कि शुरुआती सी # 3 के विकास में, संग्रह प्रारंभकर्ताओं को ICollection<T> लागू करना था, लेकिन यह बहुत ही सीमित पाया गया था। मैड्स टोरगर्सन blogged about this change, और 2006 में वापस IEnumerable की आवश्यकता के पीछे कारण।

+0

क्या LINQ क्वेरी सिंटैक्स पर एक ही तर्क लागू नहीं होगा? फिर भी इसे किसी भी इंटरफेस की आवश्यकता नहीं है, और यहां तक ​​कि "इटेटरेटर वेरिएबल" को एक प्रकार का नाम और "कहां/चयन करें" एक स्थिर विधि होने की अनुमति देता है ... – Timwi

+0

@Timwi: क्रमबद्ध करें, हालांकि यह एक प्रश्न है अभिव्यक्ति वास्तव में एक संग्रह प्रारंभकर्ता के मुकाबले एक मनमाना प्रकार के खिलाफ संकलित होगी - मुझे संदेह है कि 'जोड़ें' में उचित पैरामीटर प्रकारों के साथ 'कहां' और 'चयन करें' विधियों की तुलना में अधिक "अन्य अर्थ" हैं। यह भी ध्यान रखें कि * एक उपयुक्त इंटरफ़ेस नहीं है जो सैनिटी-चेक LINQ प्रश्नों पर लागू हो सकता था - प्रतिक्रियाशील एक्सटेंशन के बारे में सोचें, जिसमें LINQ से ऑब्जेक्ट्स के साथ कोई सामान्य इंटरफ़ेस नहीं है ... –

+6

कोई दिन नहीं जाता मेरी इच्छा के बिना .NET 2 पहला संस्करण था ... .NET में सभी क्रॉफ्ट का 9 0% .NET 1 के अस्तित्व से अपने गैर-जेनेरिक सामान के साथ आता है ... –

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

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