2012-09-14 13 views
15

संभव डुप्लिकेट:
Why was IEnumerable<T> made covariant in C# 4?क्यों IEnumerable <T> IEnumerable <out T>, IEnumerable नहीं के रूप में परिभाषित किया गया है <T>

मैं IEnumerable<T> इंटरफ़ेस परिभाषा के लिए MSDN पर एक नज़र ले रहा था, और देखो:

public interface IEnumerable<out T> : IEnumerable 

मैं सोच रहा था कि क्यों टी को out के रूप में परिभाषित किया गया है, क्यों नहीं?

public interface IEnumerable<T> : IEnumerable 

इसका कारण क्या है?

+0

क्योंकि इंटरफ़ेस covariant है – Jodrell

+1

नज़र यहाँ http://stackoverflow.com/questions/6732299/why-was-ienumerablet-made-covariant-in-c-sharp-4 – Likurg

+0

[सहप्रसरण और contravariance] (http://msdn.microsoft.com/en-us/library/ee207183) – jrummell

उत्तर

20

अधिक जानकारी here मिल सकती है।

out प्रकार पैरामीटर covariant बनाता है। यही है, आप या तो प्रकार या किसी व्युत्पन्न प्रकार का उपयोग कर सकते हैं। ध्यान दें कि out जेनरिक के साथ ही इस तरह काम करता है, विधि हस्ताक्षर में उपयोग किए जाने पर इसका एक अलग अर्थ होता है (हालांकि आप शायद पहले ही उसे जानते थे)। के रूप में StringObject से निकला

// Covariant interface. 
interface ICovariant<out R> { } 

// Extending covariant interface. 
interface IExtCovariant<out R> : ICovariant<R> { } 

// Implementing covariant interface. 
class Sample<R> : ICovariant<R> { } 

class Program 
{ 
    static void Test() 
    { 
     ICovariant<Object> iobj = new Sample<Object>(); 
     ICovariant<String> istr = new Sample<String>(); 

     // You can assign istr to iobj because 
     // the ICovariant interface is covariant. 
     iobj = istr; 
    } 
} 

आप देख सकते हैं, इंटरफ़ेस हस्ताक्षर में out, आप एक ICovariant<Object> चर के लिए एक ICovariant<String> आवंटित करने के लिए अनुमति देता है:

यहाँ उदाहरण referenced page से लिया है। out कीवर्ड के बिना, आप ऐसा करने में असमर्थ होंगे, क्योंकि प्रकार अलग होंगे।

आप कोविरिएन्स (और संबंधित contravariance) here के बारे में अधिक पढ़ सकते हैं।

अन्य उत्तर के रूप में बताया है, IEnumerable केवल कोड जैसे लिखने के लिए कोशिश कर रहा है नेट 4 में covariant किया गया था:

IEnumerable<Object> strings = new List<string>(); 

में पिछले संस्करणों में नेट 4 और बाद के संस्करणों, लेकिन नहीं संकलित कर देगा ।

6

Covariance. यह संग्रह को अपने सामान्य परम में निर्दिष्ट की तुलना में अधिक विशिष्ट या व्युत्पन्न प्रकार के आइटम सौंपने की अनुमति देता है।

IEnumerable<T> हमेशा सहकारी नहीं था; यह .NET 4 के लिए नया था, और परिवर्तन का कारण here समझाया गया है।

0

इस लक्ष्य को हासिल करने के लिए:

class Base {} 
class Derived : Base {} 

List<Derived> list = new List<Derived>(); 
IEnumerable<Base> sequence = list; 
4

out प्रकार पैरामीटर विनिर्देशक सहप्रसरण को दर्शाता है।

अभ्यास में,

अगर मैं दो इंटरफेस परिभाषित करते हैं।

ISomeInterface<T> 
{ 
} 

ISomeCovariantInterface<out T> 
{ 
} 

फिर, मैं उन्हें इस तरह लागू करता हूं।

SomeClass<T> : ISomeInterface<T>, ISomeCovariantInterface<T> 
{ 
} 

तब मैं क्योंकि covariant इंटरफ़ेस अधिक व्युत्पन्न उदाहरणों, जहां, के रूप में मानक इंटरफेस नहीं है की अनुमति देता है, इस कोड को संकलित करने के लिए

ISomeCovariantInterface<object> = new SomeClass<string>(); // works 
ISomeInterface<object> = new SomeClass<string>(); // fails 

है की कोशिश करो।

+0

+1 मुझे लगता है कि यह स्पष्ट, परिचय स्तर का उत्तर है। – TarkaDaal

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