2013-02-22 74 views
8

मैं निश्चित रूप से एक आईसीओपरपेबल के लिए एक int डाली कर सकते हैं। मैं एक आईनेमेरेबल में एक सूची या सरणी भी डाल सकता हूं।सूची <int> IENumerable <IComparable>

लेकिन मैं एक आईनेमेरेबल को एक सूची क्यों नहीं डाल सकता?

मैंने इसका परीक्षण नेट फ्रेमवर्क 4.5 और विजुअल स्टूडियो 2012 अल्टीमेट के साथ किया। परीक्षण करने के लिए

कोड:

IComparable test1; 
int t1 = 5; 
test1 = t1; //OK 

IEnumerable<int> test2; 
List<int> t2 = new List<int>(); 
int[] t3 = new int[] { 5, 6 }; 
test2 = t2; //OK 
test2 = t3; //OK 

TabAlignment[] test; 

IEnumerable<IComparable> test3; 
test3 = t2; //error Cannot implicitly convert type 'System.Collections.Generic.List<int>' to 'System.Collections.Generic.IEnumerable<System.IComparable>'. An explicit conversion exists (are you missing a cast?) 

उत्तर

12

जेनेरिक विचरण, मूल रूप से मूल्य प्रकार के लिए लागू नहीं होता। इसलिए जब आप कर सकते हैं

आप प्रत्येक मूल्य बॉक्स पूरे करने होंगे: जबकि इस मान्य है

IEnumerable<IComparable> test3 = t2.Cast<IComparable>(); 

तो क्योंकि string एक संदर्भ प्रकार है:

List<string> strings = new List<string>(); 
IEnumerable<IComparable> comparables = strings; 

... बराबर List<int> के लिए काम नहीं करता है, और जब आप जाते हैं तो आपको बॉक्स की आवश्यकता होती है।

इस स्थापना पर विचार करें::

+0

अपने जवाब के माध्यम से पढ़ने के बाद और तुलना मेरे साथ (और फिर परीक्षण किया कोड में), मुझे एहसास है कि इस उदाहरण में मेरा गलत है क्योंकि यह सूची -> सूची के बजाय सूची -> सूची से रूपांतरणों से संबंधित है, लेकिन मैं परेशान हूं कि इससे कोई फर्क क्यों पड़ता है। क्या तुम समझा सकते हो? –

+0

@ जोनएगर्टन: मुझे संदेह है कि आप उस टिप्पणी में सामान्य प्रकार के तर्क डालते हैं, लेकिन मैं उन्हें नहीं देख सकता। कोड से संबंधित बिट्स के आस-पास बैकटिक्स के साथ पुनः प्रयास करें। –

+1

@JonEgerton: ठीक है, अपने उत्तर के माध्यम से पढ़ना, फिर आपकी टिप्पणी फिर से ... - ऐसा इसलिए है क्योंकि 'सूची ' 'टी' में संविधान नहीं है, लेकिन' IEnuemrable 'है (.NET 4 के रूप में)। कक्षाएं कभी भी भिन्न नहीं हो सकती हैं। अधिक जानकारी के लिए एमएसडीएन पर "जेनेरिक भिन्नता" के लिए खोजें :) –

2

यह जेनरिक की सूची के साथ एक आम भ्रम, लेकिन मूल रूप से यदि आप इसे सामान्य इसे और अधिक समझ में आता है

public interface IA{ 
} 

public class A : IA{ 
} 

var listA = new List<A>(); 

निम्न पंक्ति काम नहीं होगा:

List<IA> listI = ListA; 

अनिवार्य रूप से ऐसा इसलिए है क्योंकि, A : IA, List<I> does not : List<A> - वे पूरी तरह से अलग प्रकार हैं।

आप आसानी से पर्याप्त कच्चा कर सकते हैं Cast पद्धति का उपयोग करके, हालांकि:

listI = ListA.Cast<IA>(); 

तो अपने मामले में तुम कर सकते हो

test3 = t2.Cast<IComparable>();