2010-07-03 12 views
5

मुझे लगता है कि मैं कुछ याद आ रही किया जाना चाहिए, मैं इस कारण है कि संकलन नहीं कर सकते हैं:आप सीमित प्रकार के टाइप किए गए एक खुले खुले जेनेरिक क्यों नहीं डाल सकते हैं?

class Foo<T> where T : Bar 
{ 
    T Bar; 
} 

abstract class Bar 
{ } 

class MyBar : Bar 
{ } 

static void Main(string[] args) 
{ 
    var fooMyBar = new Foo<MyBar>(); 
    AddMoreFoos(fooMyBar); 
} 

static void AddMoreFoos<T>(Foo<T> FooToAdd) where T : Bar 
{ 
    var listOfFoos = new List<Foo<Bar>>(); 
    listOfFoos.Add(FooToAdd); //Doesn't compile 
    listOfFoos.Add((Foo<Bar>)FooToAdd); //doesn't compile 
} 

उत्तर

9

आप थोड़ा और अधिक भ्रमित की तुलना में वे यहाँ एक सूची का उपयोग करके होने की जरूरत है बातें कर रहे हैं ... यह प्रभाव इस तरह से देखने के लिए सबसे आसान है , यह तो है कि आप तो क्यों एक Foo<MyBar> एक Foo<Bar> नहीं है एक List<Foo<Bar>>

करने के लिए एक Foo<MyBar> नहीं जोड़ सकते हैं आश्चर्य की बात नहीं है? क्योंकि जेनेरिक कक्षाएं कॉन्वेंट नहीं हैं।

जेनेरिक भिन्नता केवल सी # 4 में पेश की गई थी - और यह केवल इंटरफेस और प्रतिनिधियों के लिए काम करती है। तो तुम (सी # में 4) कर सकता है:

IEnumerable<MyBar> x = new List<MyBar>(); 
IEnumerable<Bar> y = x; 

लेकिन आप नहीं कर सका:

IList<MyBar> x = new List<MyBar>(); 
IList<Bar> y = x; 

मैं विचरण के बारे में एक पूरी बात जो आप NDC 2010 video site से डाउनलोड कर सकते हैं - बस "के लिए खोज विचरण "।

3

यह क्योंकि संकलन नहीं पड़ता कि आप एक Foo<int> के साथ अपने विधि कॉल करने के लिए गए थे तो कॉल विफल हो जाएगा: आप कोशिश कर रहे हैं अपने सामान्य पैरामीटर के लिए एक विशिष्ट प्रकार मानने के लिए।

इसके बजाय आपको var listOfFoos = new List<Foo<T>>() का उपयोग करने की आवश्यकता है, तो Add काम करना चाहिए।

(संपादित करें: समान रूप से, कास्ट काम करेगा यदि आपने Foo<T> का उपयोग किया - लेकिन आप अभी भी अपने कोड में यह नहीं मान सकते कि TBar है)।

// This won't compile 
Foo<Bar> fooBar = new Foo<MyBar>(); 

यह देखते हुए कि इस संकलन नहीं करता है:

+0

'अगर आप अपनी विधि को Foo के साथ कॉल करना चाहते हैं तो कॉल विफल हो जाएगा' => लेकिन यह कॉल सामान्य बाधा के कारण संकलित नहीं होगा, जहां टी: बार, नहीं? हालांकि, नई सूची >() के लिए +1 क्योंकि यह वास्तव में मेरी असली समस्या हल करता है! –

+0

बाधा पर अच्छा बिंदु। अगर मैंने आपकी समस्या हल की है तो आपने दूसरे जवाब को स्वीकार क्यों किया है ... (जॉन स्कीट या नहीं! ;-)) –

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