बीच क्या अंतर है <out T>
और <T>
? उदाहरण के लिए:
public interface IExample<out T>
{
...
}
बनाम
public interface IExample<T>
{
...
}
बीच क्या अंतर है <out T>
और <T>
? उदाहरण के लिए:
public interface IExample<out T>
{
...
}
बनाम
public interface IExample<T>
{
...
}
जवाबों:
out
जेनरिक में कीवर्ड निरूपित करने के लिए है कि इंटरफ़ेस में प्रकार टी covariant है प्रयोग किया जाता है। देखें सहप्रसरण और contravariance जानकारी के लिए।
क्लासिक उदाहरण है IEnumerable<out T>
। चूंकि IEnumerable<out T>
सहसंयोजक है, तो आपको निम्न कार्य करने की अनुमति है:
IEnumerable<string> strings = new List<string>();
IEnumerable<object> objects = strings;
ऊपर से दूसरी पंक्ति विफल हो जाती है अगर यह सहसंयोजक नहीं था, भले ही तार्किक रूप से यह काम करना चाहिए, क्योंकि स्ट्रिंग ऑब्जेक्ट से प्राप्त होती है। जेनेरिक इंटरफेस में विचरण से पहले C # और VB.NET (वीएस 2010 के साथ .NET 4 में) जोड़ा गया था, यह एक अनिवार्य समय त्रुटि थी।
.NET 4 के बाद IEnumerable<T>
, सहसंयोजक के रूप में चिह्नित किया गया था, और बन गया IEnumerable<out T>
। चूंकि IEnumerable<out T>
केवल इसके भीतर के तत्वों का उपयोग किया जाता है, और उन्हें कभी नहीं जोड़ता / बदलता है, इसलिए यह इसके लिए सुरक्षित है कि यह वस्तुओं के एक संग्रहणीय संग्रह के रूप में तार के एक अनगिनत संग्रह का इलाज करे, जिसका अर्थ है कि यह सहसंयोजक है ।
यह एक प्रकार के साथ काम नहीं करेगा IList<T>
, क्योंकि IList<T>
एक Add
विधि है। मान लीजिए कि यह अनुमति दी जाएगी:
IList<string> strings = new List<string>();
IList<object> objects = strings; // NOTE: Fails at compile time
आप तब कॉल कर सकते हैं:
objects.Add(new Image()); // This should work, since IList<object> should let us add **any** object
यह, निश्चित रूप से, असफल होगा - इसलिए IList<T>
सहसंयोजक चिह्नित नहीं किया जा सकता है।
इसके अलावा, btw, के लिए एक विकल्प है in
- जो तुलना इंटरफेस जैसी चीजों द्वारा उपयोग किया जाता है। IComparer<in T>
, उदाहरण के लिए, विपरीत तरीके से काम करता है। आप एक ठोस उपयोग कर सकते हैं IComparer<Foo>
एक के रूप में सीधे IComparer<Bar>
यदि Bar
का एक उपवर्ग है Foo
, क्योंकि IComparer<in T>
इंटरफेस है contravariant ।
Image
एक सार वर्ग है;) आप new List<object>() { Image.FromFile("test.jpg") };
बिना किसी समस्या के कर सकते हैं, या आप भी कर सकते हैं new List<object>() { new Bitmap("test.jpg") };
। आप के साथ समस्या यह है कि new Image()
अनुमति नहीं है (आप भी नहीं कर सकते var img = new Image();
हैं)
IList<object>
एक विचित्र उदाहरण है, यदि आप चाहते हैं कि object
आपको जेनेरिक की आवश्यकता न हो।
आसानी से in
और out
कीवर्ड के उपयोग को याद रखने के लिए (कोविरियन और कंट्रोवर्सी), हम इनहेरिटेंस को रैपर्स के रूप में चित्रित कर सकते हैं:
String : Object
Bar : Foo
विचार करें,
class Fruit {}
class Banana : Fruit {}
interface ICovariantSkinned<out T> {}
interface ISkinned<T> {}
और कार्य,
void Peel(ISkinned<Fruit> skinned) { }
void Peel(ICovariantSkinned<Fruit> skinned) { }
फ़ंक्शन जो स्वीकार करता है वह स्वीकार ICovariantSkinned<Fruit>
करने में सक्षम होगा ICovariantSkinned<Fruit>
या ICovariantSkinned<Bananna>
क्योंकि ICovariantSkinned<T>
एक सहसंयोजक इंटरफ़ेस है और Banana
एक प्रकार का है Fruit
,
फ़ंक्शन जो स्वीकार करता है ISkinned<Fruit>
वह केवल स्वीकार करने में सक्षम होगा ISkinned<Fruit>
।
" out T
" का अर्थ है कि प्रकार T
"सहसंयोजक" है। यह T
केवल सामान्य वर्ग, इंटरफ़ेस या विधि के तरीकों में एक लौटे (आउटबाउंड) मान के रूप में प्रदर्शित होने के लिए प्रतिबंधित करता है। निहितार्थ यह है कि आप सुपर के प्रकार के साथ टाइप / इंटरफ़ेस / विधि को एक बराबर कर सकते हैं T
।
जैसे ICovariant<out Dog>
को कास्ट किया जा सकता है ICovariant<Animal>
।
out
लागू किया T
जा सकता है, जब तक कि मैं इस उत्तर को नहीं पढ़ता। पूरी अवधारणा अब अधिक समझ में आता है!
आपके द्वारा पोस्ट की गई लिंक से…।
सामान्य प्रकार के मापदंडों के लिए, आउट कीवर्ड निर्दिष्ट करता है कि प्रकार पैरामीटर सहसंयोजक है ।
संपादित करें : फिर से, आपके द्वारा पोस्ट किए गए लिंक से
अधिक जानकारी के लिए, Covariance and Contravariance (C # और Visual Basic) देखें। http://msdn.microsoft.com/en-us/library/ee207183.aspx