2016-01-13 27 views
10

IEnumerator/IEnumerableyield विधियों और गेटर्स के लिए एक वर्ग प्रतीत होता है, और इसलिए ढेर पर आवंटित किया जाता है। हालांकि, List<T> जैसे अन्य .NET प्रकार बेकार स्मृति आवंटन से बचने के लिए विशेष रूप से struct गणनाकर्ताओं को वापस लौटाते हैं। सी # के गहराई से पोस्ट के त्वरित अवलोकन से, मुझे कोई कारण नहीं दिख रहा है कि यह मामला भी क्यों नहीं हो सकता है।"उपज" के लिए संकलक-जनरेटेड एन्यूमरेटर क्यों नहीं है?

क्या मुझे कुछ याद आ रही है?

+0

मुझे अभी एहसास हुआ कि चूंकि रिटर्न टाइप एक इंटरफ़ेस ('आईनेमरेबल 'या' आईन्यूमेरेटर') है, तो यह [बॉक्स किया जाएगा] (http://stackoverflow.com/questions/3032750/) वैसे भी, क्या यह सही है? इस मामले में, एक स्पष्ट रूप से टाइप किए गए गणनाकर्ता (जैसे [सूची करता है] (https://msdn.microsoft.com/en-us/library/b0yss765 (v = vs.110) को वापस करने के लिए विधि को बदला नहीं जा सका। aspx))? चूंकि यह इंटरफेस लागू करता है, इसलिए इसके सभी संदर्भ संदर्भ संरक्षित किए जाने चाहिए। (आईआईआरसी, यह काम करता है क्योंकि 'foreach' [पैटर्न द्वारा पता चला है] (https://blogs.msdn.microsoft.com/ericlippert/2011/06/30/following-the-pattern/))। – Lazlo

उत्तर

8

Servy सही ढंग से अपने प्रश्न का उत्तर - एक सवाल ने एक टिप्पणी में अपने आप को उत्तर दिया:

मैं सिर्फ महसूस किया कि जब से वापसी प्रकार एक अंतरफलक है, यह वैसे भी बॉक्सिंग जायेगा, यह सही है?

दाएं। आपका अनुवर्ती प्रश्न यह है:

स्पष्ट रूप से टाइप किए गए गणक (जैसे List<T> करता है) को वापस करने के लिए विधि को बदला नहीं जा सका?

तो यहाँ अपने विचार है कि उपयोगकर्ता लिखता है:

IEnumerable<int> Blah() ... 

और संकलक वास्तव में एक विधि है कि रिटर्न BlahEnumerable जो एक struct कि IEnumerable<int> लागू करता है उत्पन्न करता है लेकिन साथ उचित GetEnumerator आदि तरीकों और गुण जो मुक्केबाजी को दूर करने के लिए foreach की "पैटर्न मिलान" सुविधा की अनुमति देता है।

हालांकि यह एक व्यावहारिक विचार है, लेकिन जब आप किसी विधि के रिटर्न प्रकार के बारे में झूठ बोलना शुरू करते हैं तो गंभीर कठिनाइयों को शामिल किया जाता है। विशेष रूप से जब झूठ में परिवर्तन शामिल होता है चाहे विधि संरचना या संदर्भ प्रकार लौटाती है या नहीं। सभी चीजें हैं जो गलत की सोचें:

  • मान लीजिए विधि आभासी है। इसे कैसे ओवरराइड किया जा सकता है? वर्चुअल ओवरराइड विधि का रिटर्न प्रकार बिल्कुल ओवरराइड विधि से मेल खाना चाहिए। (और इसी प्रकार: विधि किसी अन्य विधि को ओवरराइड करता है, विधि एक इंटरफ़ेस की विधि लागू करती है, और इसी तरह।)

  • मान लीजिए कि विधि Func<IEnumerable<int>> प्रतिनिधि में बनाई गई है। Func<T>T में कॉन्वर्सेंट है, लेकिन कॉन्वर्सिस केवल संदर्भ प्रकार के तर्कों के प्रकार पर लागू होता है।कोड ऐसा लगता है कि यह IEnumerable<T> देता है लेकिन वास्तव में यह एक मान प्रकार देता है जो IEnumerable<T> के साथ संगत नहीं है, केवल असाइनमेंट संगत है।

  • मान लें कि हमारे पास void M<T>(T t) where T : class है और हम M(Blah()) पर कॉल करते हैं। हम TIEnumerable<int> को कम करने की उम्मीद करते हैं, जो बाधा जांच पास करता है, लेकिन संरचना प्रकार बाधा जांच पास करता है।

और इसी तरह। आप थ्रीस कंपनी के एक एपिसोड में तेजी से खत्म हो जाते हैं (लड़का मैं खुद यहां डेटिंग कर रहा हूं) जहां एक छोटा सा झूठ एक बड़ी आपदा में घूमता है। यह सब संग्रह दबाव की एक छोटी राशि को बचाने के लिए। इसके लायक नहीं।

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

+0

पूरी तरह से जवाब के लिए धन्यवाद! मैं संग्रह दबाव पर नापसंद कर रहा हूं क्योंकि मैं यूनिटी के भयानक प्रारंभिक मोनो रनटाइम गैर-पीढ़ी जीसी के साथ काम कर रहा हूं, इसलिए मैं आवंटन * बहुत * नज़दीक देख रहा हूं। – Lazlo

6

वह कक्षा केवल इंटरफ़ेस के माध्यम से कभी भी उपयोग की जाएगी। यदि यह एक संरचना थी, तो इसे कक्षा का उपयोग करने से कम कुशल बनाने के लिए 100% बार बॉक्स किया जाएगा।

आप नहीं नहीं बॉक्स यह है, यह है के रूप में, परिभाषा के द्वारा, असंभव प्रकार के रूप में संकलन समय पर उपयोग करने के लिए कर सकते हैं यह मौजूद नहीं है जब आप कोड संकलन शुरू करते हैं।

IEnumerator के कस्टम कार्यान्वयन को लिखते समय आप कोड को संकलित करने से पहले वास्तविक अंतर्निहित प्रकार का पर्दाफाश कर सकते हैं, जिससे इसे बॉक्सिंग किए बिना संभावित रूप से उपयोग किया जा सकता है।

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