2010-05-11 23 views
6

क्या मेरे पास एक प्रकार (अब इसके अर्थशास्त्र को भूलना) हो सकता है जो कि कॉन्वर्सेंट और contravariant हो सकता है?क्या मेरे पास एक प्रकार हो सकता है जो दोनों, कॉन्वर्सेंट और contravariant, यानी सब और सुपर प्रकार के साथ पूरी तरह से कवक/परिवर्तनीय है?

उदाहरण के लिए

:

public interface Foo<in out T> 
{ 
    void DoFooWith(T arg); 
} 

बंद मांस और विचरण के आलू के लिए एरिक Lippert के ब्लॉग में वहाँ कुछ और है कि इस विषय पर पर्याप्त जमीन को शामिल किया गया है के रूप में कहीं भी 4.0 में सी #।


मैं इसे किसी भी तरह बाहर की कोशिश की, न केवल यह है कि अनुमति नहीं है, लेकिन यह मुझसे कहता है मैं पूरी बात को अनदेखा कर रहा हूँ। मुझे केवल पढ़ने के लिए, केवल लिखने और भिन्नता के बीच के लिंक को समझने की आवश्यकता है।

मुझे लगता है कि मुझे कुछ और पढ़ने के लिए मिला है।

लेकिन किसी भी छोटे, एपिफेनी प्रेरक उत्तरों का स्वागत है, इस बीच।

उत्तर

7

नहीं, आप ऐसा नहीं कर सकते हैं।

मान लीजिए कि कानूनी थे। आप IFoo<Giraffe> बनाते हैं। चूंकि आईएफयू टी में कॉन्वर्सेंट है, इसलिए आप इसे टाइपएफ़ संदर्भ रूपांतरण के माध्यम से IFoo<object> पर परिवर्तित कर सकते हैं। चूंकि यह contravariant है, आप इसे IFoo<Banana> में परिवर्तित कर सकते हैं। IFoo<T> के लिए क्या संभव अर्थशास्त्र हैं जैसे कि यह संदर्भ रूपांतरण के माध्यम से केले के आईएफयू में गिरफ़ेस के आईएफयू को परिवर्तित करने में सक्षम होने के लिए समझ में आता है? Giraffes और केले के संदर्भ प्रकार होने के अलावा अन्य में कुछ भी नहीं है। आपके पास IFoo<Banana> पर संभवतः एक विधि नहीं हो सकती है जो केले लौटाती है, क्योंकि यह वास्तव में IFoo<Giraffe> का कार्यान्वयन हो सकती है; कार्यान्वयन के लेखक को केले को सौंपना कैसे होगा? आपके पास संभवतः IFoo<Banana> पर कोई विधि नहीं हो सकती है जो उसी कारण से केले लेती है; IFoo<Giraffe> के कार्यान्वयनकर्ता से आप उसे जिराफ सौंपने की उम्मीद कर रहे हैं।

यहाँ यह देखने का एक और तरीका है:

  • "टी में" का अर्थ है (लगभग) "टी केवल इनपुट की स्थिति में दिखाई देता है"।
  • "आउट टी" का अर्थ है (मोटे तौर पर) "टी केवल आउटपुट पोजीशन में दिखाई देता है"।

इसलिए "आउट टी" का मतलब होगा ... क्या? जैसा कि हमने पहले ही देखा है, इसका मतलब केवल "टी किसी भी विधि या संपत्ति में दिखाई नहीं देता है।" टी में सामान्य प्रकार बनाने का क्या मतलब है जहां आप कभी टी का उपयोग नहीं करते?

+1

असल में, जेनेरिक प्रकार जो उनके सामान्य प्रकार के तर्कों का उपयोग नहीं करते हैं, वे बेहद उपयोगी हो सकते हैं। इसलिए "प्रेत प्रकार" नामक कोड को इस तरह से लिखा जा सकता है कि गलत संचालन को स्थैतिक रूप से अस्वीकृत किया जा सकता है। कैननिकल उदाहरण शायद 'फ़ाइल ' प्रकार है, जहां टाइप 'टी' एन्कोड करता है कि फ़ाइल पढ़ने, लिखने या दोनों को अनुमति देता है भले ही कक्षा के आंतरिक भाग कभी भी' टी' का संदर्भ न दें। – kvb

+0

बेशक, आप आसानी से प्रेत प्रकारों के सुरक्षा लाभ का उल्लंघन कर सकते हैं यदि प्रकार को दोनों कॉन्वेंटेंट और contravariant के रूप में एनोटेट किया गया था, क्योंकि आप नोट करते समय 'फ़ाइल ' को 'फ़ाइल ' में परिवर्तित कर सकते हैं। – kvb

+2

@kvb: यह बेस क्लास फ़ाइल और व्युत्पन्न कक्षाएं "लिखने योग्य फ़ाइल", "पठनीय फ़ाइल" और "पठनीय और Witableable" बनाने से अलग कैसे है? जेनेरिक टाइप सिस्टम में कुछ कैप्चर क्यों करें जब इसे साधारण प्रकार की प्रणाली में आसानी से कैद किया जा सके? –

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

  • कोई संबंधित समस्या नहीं^_^