कास्ट लिस्ट <T> से लिस्ट <इंटरफ़ेस>


जवाबों:


250

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

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];

अब तुम एक में बदल सकते हैं List<Apple>एक करने के लिए IEnumerable<IFruit>सहप्रसरण की वजह से नेट 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();

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


6
जैसे वे 'अभी भी इमारत में हैं'!
आंद्रास ज़ोल्टन

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

3
@RobertNoack: "वस्तु संदर्भ" से आपका क्या तात्पर्य है? प्रत्येक तत्व का ऑब्जेक्ट संदर्भ समान है, लेकिन यह सूची संदर्भ को कास्टिंग के समान नहीं है। मान लीजिए कि आप संदर्भ कास्ट कर सकते हैं, ताकि आपके पास संकलन-समय प्रकार का List<IFruit>संदर्भ हो जो वास्तव में ए का संदर्भ था List<Apple>। यदि आप उससे एक Bananaसंदर्भ जोड़ते हैं तो आप क्या होने की उम्मीद करेंगे List<IFruit>?
जॉन स्कीट

1
ओह। मुझे लगता है कि मुझे पढ़ना सीखना होगा। मुझे लगा कि मूल जवाब में कहा गया है कि सूची में वस्तुओं को गहराई से कॉपी किया जाएगा और फिर से बनाया जाएगा जो मेरे लिए कोई मतलब नहीं था। लेकिन मैंने स्पष्ट रूप से उस हिस्से को याद किया जहां केवल एक नई सूची समान वस्तुओं के साथ बनाई गई है।
रॉबर्ट Noack

2
@ Trư :ngQuốcKhánh: मुझे पता नहीं है कि आपका कोई भी कोड कैसा दिखता है, या आपके पास कोई usingनिर्देश है System.Linqया आप इसे कॉल करने का प्रयास कर रहे हैं या नहीं, मुझे यकीन नहीं है कि आप मुझसे कैसे मदद कर पाएंगे। मेरा सुझाव है कि आप अधिक शोध करते हैं, और यदि आप अभी भी फंस गए हैं, तो आप एक न्यूनतम प्रतिलिपि प्रस्तुत करने योग्य उदाहरण के साथ एक प्रश्न पूछते हैं ।
जॉन स्कीट

6

कास्ट इटेटर और .टॉइलिस्ट ():

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

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

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


Castरिटर्न IEnumerable<T>a, not a List<T>- and no, covariance इस रूपांतरण की अनुमति नहीं देगा, क्योंकि यह असुरक्षित होगा - मेरा उत्तर देखें।
जॉन स्कीट

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

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

सही। Covariance अभी भी मदद कर सकता है, क्योंकि इसका मतलब है कि आपको Cast.NET 4 में कॉल की आवश्यकता नहीं है , इसलिए जब तक आप टाइप तर्क को निर्दिष्ट करते हैं ToList
जॉन स्कीट

5

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

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

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

के बजाय:

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

3

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

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


0

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


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

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

वैसे वे नई सूची बनाते हैं, लेकिन नए ऑपरेटर के साथ नहीं, जो इस तथ्य को नहीं बदलता है कि वे करते हैं।
पायोत्र ऑगुस्सिक

0

.Net 3.5 में, आप निम्न कार्य कर सकते हैं:

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

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


मुद्दा यह है कि इस सूची की एक प्रतिलिपि बनाई गई है, जब आप मूल सूची पर संचालन करना चाहते हैं, तो ज्यादातर समय
रोल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.