IEnumerable <T> से ICollection <T> में परिवर्तित नहीं हो सकता


91

मैंने निम्नलिखित को परिभाषित किया है:

public ICollection<Item> Items { get; set; }

जब मैं यह कोड चलाता हूं:

Items = _item.Get("001");

मुझे निम्न संदेश मिलता है:

Error   3   
Cannot implicitly convert type 
'System.Collections.Generic.IEnumerable<Storage.Models.Item>' to 
'System.Collections.Generic.ICollection<Storage.Models.Item>'. 
An explicit conversion exists (are you missing a cast?)

क्या कोई समझा सकता है कि मैं क्या गलत कर रहा हूं। मैं Enumerable, संग्रह और ToList का उपयोग करने के बीच अंतर के बारे में बहुत उलझन में हूँ ()

जानकारी जोड़ी गई

मेरे कोड में बाद में मेरे पास निम्नलिखित हैं:

for (var index = 0; index < Items.Count(); index++) 

क्या मैं आइटम को IEnumerable के रूप में परिभाषित करना ठीक होगा?


3
क्या आप _item के प्रकार और गेट (स्ट्रिंग) के हस्ताक्षर (विशेष रूप से रिटर्न प्रकार) के बारे में अधिक जानकारी प्रदान कर सकते हैं?
— डॉ। एंड्रयू बर्नेट-थॉम्पसन

इस प्रकार प्रकार क्यों नहीं बदलते? public IEnumerable<Item> Items { get; set; }क्या आपके पास ऐसा करने का कोई विशेष कारण है ICollection?
— शैडो विजार्ड कान है आपके लिए

IEnumerable <T> प्राप्त करें (स्ट्रिंग पीके);
— सामन्था जेटी स्टार

जवाबों:


113

ICollection<T>IEnumerable<T>के परिणाम को असाइन करने के लिए इनहेरिट करता है

IEnumerable<T> Get(string pk)

एक करने के लिए ICollection<T>वहाँ दो तरीके हैं।

// 1. You know that the referenced object implements `ICollection<T>`,
//    so you can use a cast
ICollection<T> c = (ICollection<T>)Get("pk");

// 2. The returned object can be any `IEnumerable<T>`, so you need to 
//    enumerate it and put it into something implementing `ICollection<T>`. 
//    The easiest is to use `ToList()`:
ICollection<T> c = Get("pk").ToList();

दूसरा विकल्प अधिक लचीला है, लेकिन इसमें बहुत बड़ा प्रदर्शन प्रभाव है। एक अन्य विकल्प परिणाम को स्टोर करना है IEnumerable<T>जब तक कि आपको ICollection<T>इंटरफ़ेस द्वारा अतिरिक्त कार्यक्षमता की आवश्यकता न हो ।

अतिरिक्त प्रदर्शन टिप्पणी

आपके पास जो लूप है

for (var index = 0; index < Items.Count(); index++)

काम करता है IEnumerable<T>लेकिन यह अक्षम है; प्रत्येक कॉल के लिए सभी तत्वों की पूर्ण गणना की Count()आवश्यकता होती है । या तो एक संग्रह और संपत्ति (कोष्ठक के बिना) का उपयोग करें या इसे एक फॉर्च लूप में परिवर्तित करें:Count

foreach(var item in Items)

1
ICollection द्वारा जोड़ी गई अतिरिक्त कार्यक्षमता क्या है?
— सामन्था जेट स्टार

7
ICollection<T>हेरफेर किया जा सकता है ( विवरण के लिए डॉक्टर देखें), जबकि IEnumerable<T>केवल गणना की जा सकती है।
— एंडर्स एबेल

मुझे कुछ ऐसा करने की आवश्यकता है जहाँ मैं अलग-अलग LINQ क्वेरी चला सकूँ। मुझे सूची में ऐसा कुछ जोड़ने या करने की आवश्यकता नहीं है। इसका मतलब है कि मैं ICollection के साथ बेहतर होगा।
— समांथा जेटी स्टार

LINQ काम करता है IEnumerable<T>इसलिए IEnumerable<T>उस मामले में पर्याप्त है।
— एंडर्स हाबिल

31

आप सीधे से परिवर्तित नहीं कर सकते IEnumerable<T>करने के लिए ICollection<T>। आप इसे में कनवर्ट करने ToListके IEnumerable<T>लिए विधि का उपयोग कर सकते हैंICollection<T>

someICollection = SomeIEnumerable.ToList();


यह मेरे लिए काम करता है। लेकिन यह मेरे लिए परिवर्तित करने के लिए एक अच्छा विचार है या मैं आइटम के प्रकार के रूप में IEnumerable का उपयोग करना बेहतर होगा। अगर मैं IEnumerable का उपयोग कर रहा हूँ तो मैं इसे बना रहा हूँ ताकि मैं अपने कार्यक्रम में बाद में ज़रूरत पड़ने पर वस्तुओं पर अधिक कार्यवाही कर सकूँ?
— सामन्था जेट स्टार

ICollection पहले से ही IEnumerable को लागू करता है। यदि आप उपलब्ध कार्यों के बारे में चिंतित हैं तो मुझे लगता है कि आपको ICollection के लिए जाना चाहिए। यह बेहतर है कि आप दोनों के बीच वास्तविक अंतर को पढ़ सकें और फिर तय करें कि वास्तव में आप क्या उपयोग करना चाहते हैं
— हसन

मैं समझने की कोशिश कर रहा हूं कि अगर मैंने टॉलिस्ट () का इस्तेमाल किया तो मुझे क्या फायदे होंगे। एक बार जब मेरे पास डेटा होगा, तो मैं आइटम के खिलाफ LINQ क्वेरी को चलाना चाहूंगा।
— समांथा जेट स्टार

ToList () काम करेगा लेकिन जैसा कि आपने अपनी टिप्पणियों में कहा है कि Get () रिटर्न एक ICollection है, इसलिए वास्तव में आपको केवल ICollection <T> के लिए एक कास्ट करने की आवश्यकता है, या बेहतर अभी तक, ICollection <T> के रिटर्न हस्ताक्षर को बदलें । ToList या ToArray का उपयोग करने से काम चल जाएगा, लेकिन यह एक अनावश्यक क्रिएट मेमोरी / कॉपी ऑपरेशन भी करेगा
— डॉ। एंड्रयू बर्नेट-थॉम्पसन

आप LINQ क्वेरी को IEnumerable और ICollection दोनों के खिलाफ चला सकते हैं। लाभ .. एक मैं अभी जानता हूँ कि गणना ICollection गिनती बनाए रखता है और IEnumerable परिणाम की गणना करता है कि कितने आइटम हैं। ICollection अतिरिक्त हटाने की विधि प्रदान करता है जो Ienumerables नहीं करता है
— Haris Hasan

1

प्रश्न पर अधिक जानकारी भेजना:

कृपया आइटम के प्रकार और गेट के हस्ताक्षर पर अधिक जानकारी प्रदान करें

दो चीजें आप आजमा सकते हैं:

  • _Item.Get (ICollection) का रिटर्न मान देने के लिए
  • _item.Get ("001") का उपयोग करने के लिए दूसरा। ToArray () या _item.Get ("001")। ToList ()

कृपया ध्यान दें कि दूसरा ऐरे कॉपी के लिए एक प्रदर्शन हिट होगा। यदि Get का हस्ताक्षर (रिटर्न प्रकार) एक ICollection नहीं है तो पहला काम नहीं करेगा, यदि यह IEnumerable नहीं है तो दूसरा काम नहीं करेगा।


प्रश्न और टिप्पणियों में आपके स्पष्टीकरण के बाद, मैं व्यक्तिगत रूप से ICITlection को _item.Get ("001") के रिटर्निंग प्रकार की घोषणा करूंगा। इसका मतलब है कि आपको कोई कास्टिंग या रूपांतरण (ToList / ToArray के माध्यम से) नहीं करना होगा, जिसमें एक अनावश्यक क्रिएट / कॉपी ऑपरेशन शामिल होगा।

// Leave this the same
public ICollection<Item> Items { get; set; }

// Change function signature here:
// As you mention Item uses the same underlying type, just return an ICollection<T>
public ICollection<Item> Get(string value); 

// Ideally here you want to call .Count on the collectoin, not .Count() on 
// IEnumerable, as this will result in a new Enumerator being created 
// per loop iteration
for (var index = 0; index < Items.Count(); index++) 

सादर,


1
हस्ताक्षर है: IEnumerable <T> जाओ (स्ट्रिंग पीके); आइटम का उपयोग आइटम रिकॉर्ड को वापस करने के लिए किया जाता है। बाद में मैंने एक रिपोर्ट बनाने के लिए इनके माध्यम से पुनरावृति की। मैं कुछ भी काम करने के लिए ठीक होगा। आपको क्या लगता है कि सबसे अच्छा प्रकार का डेटाटाइप क्या होगा?
— सामन्था JT Star

1
मेरा सुझाव है कि आइटम को मिलान करने के लिए IEnumerable <T> के आइटम्स को परिवर्तित करें, या आइटम से मिलान करने के लिए गेट के ICollection <T> के प्रकार को बदलें। मुझे लगता है कि ये दोनों एक ही अंतर्निहित प्रकार हैं जो अलग-अलग घोषित किए गए हैं? यदि वे एक ही प्रकार के हैं तो आप ToList () या ToArray () का उपयोग करने से बचना चाहते हैं क्योंकि यह एक अनावश्यक मेमोरी आवंटन और सरणी कॉपी करता है। यदि वे एक ही प्रकार के नहीं हैं तो आपको कुछ रूपांतरण करना होगा
— डॉ। एंड्रयू बर्नेट-थॉम्पसन

मैंने यह प्रश्न करने के लिए जोड़ा कि मैं बाद में आइटम का उपयोग कहां कर रहा हूं। एक ही अंतर्निहित प्रकार कहते समय आप सही हैं।
— सामन्था जेटी स्टार

ठीक है, तो मैं बस गेट के रिटर्न प्रकार को बदल दूंगा, क्योंकि तब आपको किसी भी रूपांतरण (ToList / ToArray, जो धीमा है), या कास्टिंग करने की आवश्यकता नहीं है। आशा है कि यह मदद करता है :)
— डॉ। एंड्रयू बर्नेट-थॉम्पसन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.