कोड के निम्नलिखित भाग में मुझे elements
से baseElements
पर अनुमानित रूप से डालने में सक्षम होने की उम्मीद है क्योंकि TBase
IBase
पर स्पष्ट रूप से परिवर्तनीय है।क्या यह सी # 4 में एक कॉन्वर्स बग है?
public interface IBase { }
public interface IDerived : IBase { }
public class VarianceBug
{
public void Foo<TBase>() where TBase : IBase
{
IEnumerable<TBase> elements = null;
IEnumerable<IDerived> derivedElements = null;
IEnumerable<IBase> baseElements;
// works fine
baseElements = derivedElements;
// error CS0266: Cannot implicitly convert type
// 'System.Collections.Generic.IEnumerable<TBase>' to
// 'System.Collections.Generic.IEnumerable<IBase>'.
// An explicit conversion exists (are you missing a cast?)
baseElements = elements;
}
}
हालांकि, मुझे टिप्पणी में उल्लिखित त्रुटि मिलती है।
कल्पना से हवाला देते हुए:
एक प्रकार
T<A1, …, An>
विचरण-परिवर्तनीय एक प्रकारT<B1, …, Bn>
अगरT
या तो एक इंटरफेस या एक प्रतिनिधि प्रकार संस्करण प्रकार पैरामीटरT<X1, …, Xn>
साथ घोषणा की, और प्रत्येक संस्करण प्रकार पैरामीटर के लिए है करने के लिए है निम्न में सेXi
एक रखती है:
Xi
covariant है और एक अंतर्निहित संदर्भ या पहचान रूपांतरणसे मौजूद हैBi
को
Xi
contravariant है और एक अंतर्निहित संदर्भ या पहचान रूपांतरणBi
से करने के लिएAi
Xi
अपरिवर्तनीय है मौजूद है और एक पहचान रूपांतरणBi
जाँच करने के लिए Ai
से मौजूद है मेरा कोड, यह spec के साथ संगत प्रतीत होता है:
IEnumerable<out T>
एक अंतरफलक प्रकारIEnumerable<out T>
संस्करण प्रकार मानकों के साथ घोषित किया जाता हैT
TBase
सेIBase
एक अंतर्निहित संदर्भ रूपांतरण मौजूद है
तो - क्या यह सी # 4 कंपाइलर में एक बग है?
जब आप स्पष्ट रूप से डाली तो क्या होगा? कंपाइलर का कहना है कि एक है। चूंकि आप इसे कम कर रहे हैं, थोड़े समझ में आता है ..? – flq
बस इसे स्पष्ट करने के लिए - यह आपकी आखिरी गोली है "एक अंतर्निहित संदर्भ रूपांतरण टीबीज़ से आईबीएएस तक मौजूद है" जो असत्य है (जब तक आप 'वर्ग' नहीं जोड़ते)। यह असाइन किया जा सकता है, लेकिन यह * संदर्भ * एक संदर्भ-रूपांतरण नहीं है। 'वर्ग' के बिना यह एक "बाधित" रूपांतरण है, जो कुछ जादू है जो संदर्भ-प्रकारों और मूल्य-प्रकारों पर समान आईएल कॉल विधियों (संपत्ति एक्सेसर्स समेत) को उसी तरह देता है: http://msdn.microsoft .com/en-us/library/system.reflection.emit.opcodes.constrained.aspx –
चार्ल्स: आप गलत हैं - पहला असाइनमेंट काम करता है (मेरी मशीन (टीएम) पर काम करता है)। –