2010-08-31 15 views
6

यह स्पष्ट है कि T[] सरणी प्रकार covariant नहीं है क्योंकि T[] के तत्वों को इंडेक्स द्वारा सेट किया जा सकता है।यह कैसे है कि [[] टी [] के लिए जाति योग्य है?

और फिर भी, एक U[] एक T[] को कोई शिकायत बिना संकलक से जब तक UT से निकला है के रूप में ढाला जा सकता है।

Man[] men = new[] { new Man("Aaron"), new Man("Billy"), new Man("Charlie") }; 
Person[] people = (Person[])men; 
ऊपर कोड ऐसा लगता है कि men और people ही Array वस्तु के लिए एक संदर्भ पकड़ पा रहे हैं में

men[0] = new Man("Aidan") को सेट करने का प्रभाव people[0] पर देखा जा सकता है। इसी तरह people[0] = new Woman("Debbie") का प्रयास ArrayTypeMismatchException रनटाइम * पर होता है।

क्या इसका मतलब यह है कि T[] प्रकार वास्तव में प्रत्येक set कॉल पर टाइपिंग जांच करता है? ऐसा लगता है कि अगर यह इस तरह से सरणी डालने की अनुमति है तो यह आवश्यक होना चाहिए।

मुझे लगता है कि मेरा प्रश्न है: यह कैसे संभव है? यह मुझे स्पष्ट है कि U[]T[] से प्राप्त नहीं होता है। यह अस्पष्ट है कि मैं कभी भी अपने स्वयं के प्रकार को परिभाषित कर सकता हूं जो इस तरह से काम करेगा: वास्तव में इनवेरिएंट लेकिन अधिनियम कॉन्वेंटेंट है।


* हालांकि सरणी विचरण जाहिरा तौर पर CLR ने अनुमति दी है, किसी भी भाषा सरणी प्रकार के बीच कास्टिंग नामंज़ूर कर सकता है। हालांकि, ऐसा लगता है कि इस व्यवहार VB.NET में समान होता है:

Dim men = New Man() { New Man("Aaron"), New Man("Billy"), New Man("Charlie") } 
Dim people = CType(men, Person()) 
+1

क्या आप इसे किसी विशेष भाषा के साथ टैग कर सकते हैं, हम में से उन लोगों के लिए जो आप नहीं जानते कि आप कौन सी बात कर रहे हैं? –

+0

@ फिलिप: मैं * कर सकता था, लेकिन यह वीबीएनईटी और सी # के लिए समान रूप से लागू लगता है। यही कारण है कि मैं सिर्फ .NET टैग के साथ गया था। –

+0

एक भाषा पूरी तरह से इसे अस्वीकार नहीं कर सकती है - भाषा एक्स में लिखी गई विधि भाषा वाई से एक कॉवररीएटेड सरणी प्राप्त कर सकती है। – SLaks

उत्तर

7

यह सरणियों की एक विशेष व्यवहार है और किसी भी अन्य प्रकार में दोहराया नहीं जा सकता है।

It is generally regarded as a mistake

+1

तो यह सरणी के साथ कैसे काम करता है? –

+1

@ डैन: सीएलआर में विशेष जादू। हाँ; प्रत्येक सरणी सेट (एक गैर-मुहरबंद प्रकार का) एक प्रकार का चेक करता है। – SLaks

+0

@ दैन ताओ क्या आपने लिंक किए गए पोस्ट को देखा? यह समझाया गया है – jeroenh

2

यह केवल इसलिए काम करता है क्योंकि यह एक विशेष विशेषता है जो सीएलआर का हिस्सा है। तकनीकी रूप से वे नहीं हैं, भले ही Arrays स्वचालित रूप से covariant हैं। कंपाइलर्स को सिर्फ यह पता होना चाहिए और उचित प्रकार के चेक उत्पन्न करना होगा।

हालांकि कुछ इस विशेषता को गलती मानते हैं, तो टाइपएफ़ संग्रह और सामान्य इंटरफ़ेस कॉन्वर्सिस से पहले होना बहुत महत्वपूर्ण था। आप बिना किसी सरणी को सॉर्ट करने के लिए फ़ंक्शन लिखने में भी सक्षम नहीं होंगे।

+0

कंपाइलरों को कास्टिंग नियमों को छोड़कर, इसे जानने की आवश्यकता नहीं है। यह रनटाइम द्वारा संभाला जाता है। – SLaks

1

एरिक ने इसे यहां स्पष्ट रूप से समझाया: http://blogs.msdn.com/b/ericlippert/archive/2007/10/17/covariance-and-contravariance-in-c-part-two-array-covariance.aspx

लघु पुन: प्रारंभ: यदि डी बी विरासत में है तो डी [] बी [] के लिए अनुकूल है। मान लें कि डी 2 भी बी से विरासत में है, फिर

B[] b = new D[10]; 
b[0] = new D1(); 

अपवाद फेंकता है। हाँ, यह अच्छा नहीं है लेकिन ऐसा है।

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

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