2008-10-29 6 views
103

मैं पीडीसी 2008 में शामिल नहीं हुआ, लेकिन मैंने कुछ खबरें सुनाई कि सी # 4.0 जेनेरिक कॉन्वर्सिस और कॉन्ट्रैक्ट-वेरिएंस का समर्थन करने के लिए घोषित किया गया है। यही है, List<string> को List<object> पर असाइन किया जा सकता है। यह कैसे हो सकता है?जेनरिक कॉन्वर्सिस और कॉन्ट्रा-वेरिएंस सी # 4.0 में कार्यान्वित कैसे किया जाता है?

जॉन स्कीट की किताब सी # में गहराई में, यह क्यों सी # जेनरिक सहप्रसरण और विपरीत विचरण का समर्थन नहीं करता समझाया गया है। यह मुख्य रूप से सुरक्षित कोड लिखने के लिए है। अब, सी # 4.0 उन्हें समर्थन देने के लिए बदल गया। क्या यह अराजकता लाएगा?

कोई भी सी # 4.0 के बारे में विवरण कुछ स्पष्टीकरण दे सकता है?

+0

यहाँ एक अच्छा लेख है कि में प्रतिनिधियों और इंटरफेस पर आगामी सहप्रसरण और विपरीत विचरण कार्यान्वयन को शामिल किया गया है सी # 4.0: [LINQ फार्म: Covariance और Contravariance सी # 4.0] (http://blogs.msdn.com/charlie/archive/2008/10/28/linq-farm-covariance-and-contravariance-in-visual-studio-2010.aspx) – CMS

+0

एंडर्स नोरासे [सी # 4।0 - कॉन्वर्सिस और कॉन्ट्रैक्ट-वेरिएंस] (http://web.archive.org/web/20100227031805/http://andersnoras.com/post/100795246/c-4-0-covariance-and-contra-variance) अवधारणा और शो, कि यह पहले ही आईएल में .NET 2.0 के बाद से समर्थित है। –

उत्तर

152

भिन्नता केवल सुरक्षित तरीके से समर्थित होगी - वास्तव में, सीएलआर के पास पहले से ही क्षमताओं का उपयोग करना है। तो List<Banana> को List<Fruit> (या जो कुछ भी था) के रूप में उपयोग करने की कोशिश करने की पुस्तक में मैं जो उदाहरण देता हूं, वह अभी भी काम नहीं करेगा - लेकिन कुछ अन्य परिदृश्य भी होंगे।

सबसे पहले, यह केवल इंटरफेस और प्रतिनिधियों के लिए समर्थित होगा।

दूसरा, इंटरफ़ेस/प्रतिनिधि के लेखक को in (contravariance के लिए) या out (कॉन्वर्सिस के लिए) के रूप में टाइप पैरामीटर को सजाने के लिए आवश्यक है। सबसे स्पष्ट उदाहरण IEnumerable<T> है जो केवल आपको कभी भी "आउट" मान लेने देता है - यह आपको नए जोड़ने की अनुमति नहीं देता है। यह IEnumerable<out T> बन जाएगा। इससे टाइप सुरक्षा को बिल्कुल नुकसान नहीं पहुंचाता है, लेकिन उदाहरण के लिए IEnumerable<object> लौटने के लिए घोषित विधि से IEnumerable<string> वापस करने देता है।

इंटरफेस का उपयोग करने के लिए ठोस उदाहरण देने के लिए contravariance कठिन है, लेकिन यह एक प्रतिनिधि के साथ आसान है। Action<T> पर विचार करें - यह केवल एक विधि का प्रतिनिधित्व करता है जो T पैरामीटर लेता है। यह को Action<string> के रूप में निर्बाध रूप से परिवर्तित करने में सक्षम होना अच्छा होगा - object पैरामीटर लेने के लिए कोई भी विधि ठीक होने जा रही है जब इसे string के साथ प्रस्तुत किया जाता है। बेशक, सी # 2 में पहले से ही कुछ हद तक प्रतिनिधियों का सहानुभूति और contravariance है, लेकिन एक प्रतिनिधि प्रकार से दूसरे में एक वास्तविक रूपांतरण के माध्यम से (एक नया उदाहरण बनाते हैं) - उदाहरण के लिए P141-144 देखें। सी # 4 इसे और अधिक सामान्य बना देगा, और (मुझे विश्वास है) रूपांतरण के लिए एक नया उदाहरण बनाने से बचेंगे। (यह इसके बजाय एक संदर्भ रूपांतरण होगा।)

आशा है कि यह थोड़ा सा साफ़ हो जाए - कृपया मुझे बताएं अगर यह समझ में नहीं आता है!

+3

तो, क्या इसका मतलब यह है कि यदि कक्षा को "सूची " घोषित किया गया है, तो उसके पास सदस्य शून्य कार्य नहीं होना चाहिए जैसे "शून्य जोड़ें (टी obj)"? सी # 4.0 कंपाइलर उस पर त्रुटि की रिपोर्ट करेगा, है ना? –

+1

मॉर्गन: यह निश्चित रूप से मेरी समझ है, हां। –

+4

फिर भी एसओ पर आपके उत्तरों में से एक ने तुरंत मुझे कुछ कोड सुधारने में मदद की है। धन्यवाद! – Mark

5

नहीं कि जॉन ने इसे पहले ही कवर नहीं किया है, लेकिन यहां एरिक लिपर्ट से ब्लॉग और वीडियो के कुछ लिंक दिए गए हैं। वह उदाहरणों के साथ व्याख्या करने का एक अच्छा काम करता है।

https://blogs.msdn.microsoft.com/ericlippert/2007/10/16/covariance-and-contravariance-in-c-part-one/

वीडियो:

https://www.youtube.com/watch?v=3MQDrKbzvqU

https://www.youtube.com/watch?v=XRIadQaBYlI

https://www.youtube.com/watch?v=St9d2EDZfrg

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