C # 4.0 में जेनेरिक कोवरियन और कॉन्ट्रा-वेरिएशन कैसे लागू किया जाता है?


106

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

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

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


यहाँ एक अच्छा लेख है जो C # 4.0 में प्रतिनिधियों और इंटरफेस पर आगामी सह- प्रसार और गर्भ
CMS

एंडर्स नॉरसे सी # 4.0 में बताते हैं - कोविरियन और कॉन्ट्रासेप्शन- कांसेप्ट और कॉन्सेप्ट - वैरिएशन से पता चलता है कि यह .NET 2.0 के बाद से IL में आज ही सपोर्ट करता है।
थॉमस फ्रायडेनबर्ग

जवाबों:


155

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

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

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

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

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


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

1
मॉर्गन: यह निश्चित रूप से मेरी समझ है, हाँ।
जॉन स्कीट

4
फिर से एसओ पर आपके एक जवाब ने तुरंत मुझे कुछ कोड सुधारने में मदद की। धन्यवाद!
मार्क

@ अरक-कुन: हाँ, मुझे इसकी जानकारी है। इसलिए एक ही वाक्य में "अभी भी काम नहीं करेगा"। (और मुझे इसके कारणों के बारे में भी पता है।)
जॉन स्कीट

@JonSkeet यह सही है कि "आप केवल एक का उपयोग कर सकते है List<Banana>के रूप में एक IList<Fruit>के रूप में @ आर्क-कुन ने कहा,"? यदि हां, तो यह कैसे संभव है, हालांकि IList<T>इंटरफ़ेस का प्रकार पैरामीटर सहसंयोजक (नहीं out T, लेकिन बस T) के रूप में परिभाषित नहीं किया गया है ।
गेहूँ

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

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