दिलचस्प पोस्ट
पांडा डेटाफ्रेम को सीएसवी फ़ाइल में लिख रहे हैं उदाहरण के लिए और क्लास में क्या अंतर है। एसेस्नेबलफॉम (…)? एंड्रॉइड: एमुलेटर में वाईफाई का अनुकरण? पायथन में स्ट्रिंग से गैर प्रिंट करने योग्य वर्ण स्ट्रिपिंग स्तंभों की असमान संख्या के लिए do.call (rbind, सूची) एक <a> लिंक पर क्लिक करते समय पुष्टिकरण संवाद कैसे प्रदर्शित किया जाए? सर्वर या phpMyADMIN तक पहुंच के बिना एसक्यूएल तालिका निर्यात करने का आसान तरीका मैं प्राथमिक सारांश में एंड्रॉइड पसंद के वर्तमान मूल्य को कैसे प्रदर्शित करूं? आकार रंग गतिशील रूप से कैसे परिवर्तित करें? क्या "शैली परिवर्तन" घटना को सुनना संभव है? WPF में बिटमैप इमेज ताला फ़ाइल है पहली बार किसी आईओएस ऐप को लॉन्च करते समय पता लगाएं? घुड़सवार और अस्पष्ट जावास्क्रिप्ट के बीच अंतर जावा में पूर्णांक की श्रेणी get_headers असंगति

सी # में कॉओरिएंट और कॉन्ट्राएरिएन्ट इंटरफेस को समझना

मैं इन पर एक पाठ्यपुस्तक में आया हूं जो मैं सी # पर पढ़ रहा हूं, लेकिन मुझे उन्हें समझने में कठिनाई हो रही है, शायद संदर्भ की कमी के कारण।

क्या वे क्या हैं और क्या वे बाहर के लिए उपयोगी हैं का एक संक्षिप्त संक्षिप्त विवरण है?

स्पष्टीकरण के लिए संपादित करें:

कोवैरिंट इंटरफ़ेस:

interface IBibble<out T> . . 

Contravian इंटरफ़ेस:

 interface IBibble<in T> . . 

वेब के समाधान से एकत्रित समाधान "सी # में कॉओरिएंट और कॉन्ट्राएरिएन्ट इंटरफेस को समझना"

<out T> , आप पदानुक्रम में एक ऊपर की तरफ अंतरफलक संदर्भ का इलाज कर सकते हैं।

<in T> In <in T> , आप इंटरफेस संदर्भ को ऊंचाइयों में एक नीचे के रूप में इलाज कर सकते हैं।

मुझे इसे अंग्रेजी शब्दों में समझाने की कोशिश करें

मान लीजिए कि आप अपने चिड़ियाघर से जानवरों की एक सूची पुनः प्राप्त कर रहे हैं, और आप उन पर कार्रवाई करने का इरादा रखते हैं। सभी जानवरों (आपके चिड़ियाघर में) का एक नाम है, और एक अद्वितीय आईडी है कुछ जानवर स्तनधारी हैं, कुछ सरीसृप हैं, कुछ उभयचर हैं, कुछ मछली हैं, आदि। लेकिन वे सभी जानवर हैं।

इसलिए, आपकी जानवरों की सूची (जिसमें विभिन्न प्रकार के जानवर शामिल हैं) के साथ, आप कह सकते हैं कि सभी जानवरों का नाम है, इसलिए जाहिर है कि सभी जानवरों के नाम को प्राप्त करना सुरक्षित होगा।

हालांकि, अगर आपके पास केवल पक्षियों की सूची है, लेकिन उन्हें जानवरों की तरह व्यवहार करने की आवश्यकता है, तो क्या यह काम करता है? Intuitively, यह काम करना चाहिए, लेकिन सी # 3.0 और पहले में, कोड का यह टुकड़ा संकलित नहीं होगा:

 IEnumerable<Animal> animals = GetFishes(); // returns IEnumerable<Fish> 

इसका कारण यह है कि कंपाइलर "जानना" नहीं करता है कि आप इसे पुनः प्राप्त करने के बाद जानवरों के संग्रह के साथ क्या करना चाहते हैं या क्या कर सकते हैं । सभी के लिए यह जानता है कि, एक सूची को किसी वस्तु को वापस सूची में डाल देने के लिए, IEnumerable<T> माध्यम से एक रास्ता हो सकता है, और यह संभवतः आपको किसी ऐसे जानवर को डालने की अनुमति देगा जो एक मछली नहीं है, एक संग्रह में, जिसमें केवल शामिल होना चाहिए मछली।

दूसरे शब्दों में, संकलक यह गारंटी नहीं दे सकता है कि इसकी अनुमति नहीं है:

 animals.Add(new Mammal("Zebra")); 

तो कंपाइलर सिर्फ पूर्ण रूप से आपके कोड को संकलित करने से इनकार करता है। यह संप्रदाय है

चलो भ्रांत को देखने

चूंकि हमारे चिड़ियाघर सभी जानवरों को संभाल सकता है, इसलिए यह निश्चित रूप से मछली को नियंत्रित कर सकता है, तो चलो हमारे चिड़ियाघर में कुछ मछली जोड़ने की कोशिश करें।

सी # 3.0 और पहले में, यह संकलित नहीं करता है:

 List<Fish> fishes = GetAccessToFishes(); // for some reason, returns List<Animal> fishes.Add(new Fish("Guppy")); 

यहां, कंपाइलर कोड के इस भाग को अनुमति दे सकता है , भले ही इस पद्धति की List<Animal> वजह से सभी मछली जानवर हैं, इसलिए यदि हम इस प्रकार को सिर्फ बदलते हैं:

 List<Animal> fishes = GetAccessToFishes(); fishes.Add(new Fish("Guppy")); 

तो यह काम करेगा, लेकिन संकलक निर्धारित नहीं कर सकता कि आप ऐसा करने की कोशिश नहीं कर रहे हैं:

 List<Fish> fishes = GetAccessToFishes(); // for some reason, returns List<Animal> Fish firstFist = fishes[0]; 

चूंकि सूची वास्तव में जानवरों की एक सूची है, इसलिए इसकी अनुमति नहीं है

तो विपरीत- और सह-विचलन है कि आप ऑब्जेक्ट संदर्भों के साथ कैसे व्यवहार करते हैं और आप उनके साथ क्या करने की अनुमति है।

सी # 4.0 में in और out कीवर्ड में विशेष रूप से इंटरफ़ेस को एक या दूसरे के रूप में चिह्नित किया जाता है अंदर के साथ, आपको इनपुट- स्थितियों में जेनेरिक प्रकार (आमतौर पर टी) रखने की अनुमति है, जिसका अर्थ है विधि तर्क और केवल-लेखन गुण।

out साथ, आपको आउटपुट- स्थितियों में जेनेरिक प्रकार रखने की अनुमति है, जो विधि वापसी मान है, केवल-पढ़ने के गुण, और आउट पैरामीटर पैरामीटर हैं।

यह आपको कोड के साथ करने का इरादा करने की अनुमति देगा:

 IEnumerable<Animal> animals = GetFishes(); // returns IEnumerable<Fish> // since we can only get animals *out* of the collection, every fish is an animal // so this is safe 

List<T> पर दोनों में और बाहर की दिशाएं हैं, इसलिए यह न तो सह-भिन्न है या न ही उल्टी-भिन्न है, लेकिन एक अंतरफलक है जो आपको ऑब्जेक्ट्स को जोड़ने की अनुमति देता है, जैसे:

 interface IWriteOnlyList<in T> { void Add(T value); } 

आपको यह करने की अनुमति देगा:

 IWriteOnlyList<Fish> fishes = GetWriteAccessToAnimals(); // still returns IWriteOnlyList<Animal> fishes.Add(new Fish("Guppy")); <-- this is now safe 

यहां कुछ वीडियो हैं जो अवधारणाओं को दिखाते हैं:

  • कोवेरियेंस एंड कॉन्ट्राएरिएंस – वीएस -2010 सी # 3 का 1 भाग
  • कोवेरियेंस एंड कॉन्ट्राएरिएंस – वीएस -2010 सी # 3 का भाग 2
  • कोवेरियेंस एंड कॉन्ट्राएरिएंस – वीएस -2010 सी # 3 का 3 भाग

यहां एक उदाहरण है:

 namespace SO2719954 { class Base { } class Descendant : Base { } interface IBibbleOut<out T> { } interface IBibbleIn<in T> { } class Program { static void Main(string[] args) { // We can do this since every Descendant is also a Base // and there is no chance we can put Base objects into // the returned object, since T is "out" // We can not, however, put Base objects into b, since all // Base objects might not be Descendant. IBibbleOut<Base> b = GetOutDescendant(); // We can do this since every Descendant is also a Base // and we can now put Descendant objects into Base // We can not, however, retrieve Descendant objects out // of d, since all Base objects might not be Descendant IBibbleIn<Descendant> d = GetInBase(); } static IBibbleOut<Descendant> GetOutDescendant() { return null; } static IBibbleIn<Base> GetInBase() { return null; } } } 

इन अंकों के बिना, निम्नलिखित संकलित हो सकता है:

 public List<Descendant> GetDescendants() ... List<Base> bases = GetDescendants(); bases.Add(new Base()); <-- uh-oh, we try to add a Base to a Descendant 

या यह:

 public List<Base> GetBases() ... List<Descendant> descendants = GetBases(); <-- uh-oh, we try to treat all Bases as Descendants 

इस पोस्ट में मैंने इस विषय पर सबसे अच्छा पढ़ा है

संक्षेप में, सह प्रकार / अनैतिक / अन्वेषक स्वचालित प्रकार की ढलाई के साथ सौदों (आधार से व्युत्पन्न और उपाध्यक्ष विपरीत)। उन प्रकार के डाट केवल तभी संभव होते हैं जब कुछ गारंटियां कास्टेड ऑब्जेक्ट्स पर किए गए पढ़ने / लिखने के कार्य के संदर्भ में सम्मानित हो जाती हैं। अधिक जानकारी के लिए पोस्ट पढ़ें।