2012-01-19 30 views

उत्तर

149

आप नहीं डाल सकता यह (संरक्षण संदर्भ पहचान) - वह असुरक्षित होगा। उदाहरण के लिए:

public interface IFruit {} 

public class Apple : IFruit {} 
public class Banana : IFruit {} 

... 

List<Apple> apples = new List<Apple>(); 
List<IFruit> fruit = apples; // Fortunately not allowed 
fruit.Add(new Banana()); 

// Eek - it's a banana! 
Apple apple = apples[0]; 

अब आप एक IEnumerable<IFruit> करने के लिए एक List<Apple> .NET में सहप्रसरण की वजह से परिवर्तित कर सकते हैं 4/सी # 4, लेकिन यदि आप एक List<IFruit> चाहते आप एक नई सूची बनाने के लिए होगा। उदाहरण के लिए:

// In .NET 4, using the covariance of IEnumerable<T> 
List<IFruit> fruit = apples.ToList<IFruit>(); 

// In .NET 3.5 
List<IFruit> fruit = apples.Cast<IFruit>().ToList(); 

लेकिन इस नहीं मूल सूची कास्टिंग के रूप में एक ही है - क्योंकि अब वहाँ दो अलग सूची नहीं है। यह सुरक्षित है, लेकिन आपको यह समझने की आवश्यकता है कि एक सूची में किए गए परिवर्तन अन्य सूची में नहीं देखा जाएगा। (वस्तुओं कि सूचियों का उल्लेख करने के संशोधन निश्चित रूप से देखा करने के लिए किया जाएगा,।)

+5

@Downvoter: टिप्पणी करने की देखभाल? –

+5

जैसे वे 'अभी भी इमारत में हैं'! –

+1

कॉन्वर्सिस सूची और नई सूची () करने के बीच क्या अंतर है; फिर मूल सूची पर एक foreach और प्रत्येक आइटम IFruit सूची में जोड़ने? Foreach रास्ता में ... वस्तु संदर्भ वही होगा, सही? तो ... यदि यह सच है, तो यह मुझे व्यक्तिगत रूप से थोड़ा समझ में आता है कि आप पूरी सूची को सीधे नहीं डाले जा सकते हैं। ? –

0

नया List<IDic> बनाकर और सभी तत्वों को स्थानांतरित करके यह केवल संभव है।

+0

कोई टिप्पणी क्यों कम हो गई, क्योंकि सामान्य अर्थ अन्य सभी उत्तरों के समान है? –

+0

मेरा अनुमान आपको डाउनवॉट किया जाएगा क्योंकि आपने कहा था कि एक नई सूची बनाना संभव था, लेकिन अन्य ने इसके विपरीत पोस्ट किया है ... हालांकि मेरा डाउनवोट नहीं) – musefan

+0

वैसे वे नई सूचियां बनाते हैं लेकिन नए ऑपरेटर के साथ नहीं तथ्य नहीं है कि वे करते हैं। –

4

एक कास्ट इटरेटर और .ToList():

List<IDic> casted = input.Cast<IDic>().ToList() चाल करेंगे।

मूल रूप से मैंने कहा कि कॉन्वर्सिस काम करेगा - लेकिन जैसा कि जॉन ने सही तरीके से बताया है; नहीं, यह नहीं होगा!

और मूल रूप से मैं भी मूर्खता से दूर छोड़ दिया ToList() कॉल

+0

'कास्ट' एक 'IENumerable ' लौटाते हैं, 'सूची ' नहीं - और नहीं, covariance * इस रूपांतरण की अनुमति नहीं देगा, क्योंकि यह असुरक्षित होगा - मेरा उत्तर देखें। –

+0

आपके द्वारा लिंक किए गए पृष्ठ से: "केवल इंटरफ़ेस प्रकार और प्रतिनिधि प्रकारों में भिन्न प्रकार के पैरामीटर हो सकते हैं" –

+0

@ जोन - मुझे एहसास हुआ कि आपकी टिप्पणी पढ़ने से पहले 'ToList() 'गायब था; लेकिन हाँ जैसा कि आपने पाठ्यक्रम दिखाया है कोविरेन्स काम नहीं करेगा! रवींद्र! –

1

आप LINQ का उपयोग कर सकते हैं तो आप ऐसा कर सकते हैं ...

List<Client> clientList = new List<Client>(); 
List<IDic> list = clientList.Select(c => (IDic)c).ToList(); 
1
List<Client> listOfA = new List<Client>(); 
List<IDic> list = listOfA.Cast<IDic>().ToList(); 
1

मैं भी इस समस्या थी और जॉन स्कीट के जवाब को पढ़ने के बाद मैं List<T> का उपयोग कर IEnumerable<T> उपयोग करने के लिए से अपने कोड को संशोधित किया। हालांकि यह के ओपी के मूल प्रश्न का उत्तर नहीं देता है, मैं List<Client> से List<IDic> पर कैसे जा सकता हूं, यह ऐसा करने की आवश्यकता से बचता है और इस प्रकार इस समस्या का सामना करने वाले अन्य लोगों के लिए सहायक हो सकता है। यह निश्चित रूप से मानता है कि List<IDic> के उपयोग की आवश्यकता वाले कोड को आपके नियंत्रण में है।

उदाहरण के लिए:

public void ProcessIDic(IEnumerable<IDic> sequence) 
{ 
    // Implementation 
} 

बजाय:

public void ProcessIDic(List<IDic> list) 
{ 
    // Implementation 
} 
0

नेट 3.5 में, आप क्या कर सकते हैं निम्नलिखित:

List<ISomeInterface> interfaceList = new List<ISomeInterface>(list.Cast<ISomeInterface>()); 

इस मामले में सूची के लिए निर्माता लेता है एक IEnumerable।
सूची यद्यपि केवल IENumerable में परिवर्तनीय है। भले ही myObj ISomeInterface में परिवर्तनीय हो सकता है, प्रकार IENumerable IENumerable में परिवर्तनीय नहीं है।

+0

मुद्दा यह है कि यह सूची की एक प्रति बनाता है, अधिकांश समय आप मूल सूची पर संचालन करना चाहते हैं – rolls

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