स्वतंत्र रूप से सूची <T> और IEnumerable <T> के बीच कनवर्ट करें


103

मैं List<MyObject>एक IEnumerable<MyObject>और फिर वापस फिर से कैसे परिवर्तित कर सकता हूं ?

मैं ऐसा करना चाहता हूं ताकि लिस्ट पर लाइनक्यू स्टेटमेंट की एक श्रृंखला चल सके, जैसे Sort()


यह इस प्रश्न में शामिल है stackoverflow.com/questions/31708/…
जॉन

जवाबों:


148
List<string> myList = new List<string>();
IEnumerable<string> myEnumerable = myList;
List<string> listAgain = myEnumerable.ToList();

30
हालांकि खबरदार कि myEnumarable myList के समान ऑब्जेक्ट उदाहरण है, लेकिन listAgain myEnumerable के समान ऑब्जेक्ट उदाहरण नहीं है। इस पर निर्भर करता है कि आप क्या करना चाहते हैं और myEnumerable क्या है, "List <string> listAgain = myEnumerable as List <string>;" बेहतर हो सकता है।
क्रिसडब्ल्यू

1
क्रिस: ओह हाँ, आप निश्चित रूप से सही हैं, लेकिन IEnumerable <T> इंटरफ़ेस अपरिवर्तनीय है, इसलिए यह उस दिशा में समस्या पैदा नहीं करेगा और वापस कास्टिंग करना केवल तब गंदा लगता है जब आपके पास एक फ़ंक्शन होता है जो प्रकार की सुरक्षा का ध्यान रखेगा।
तमस Czinege

1
तुम भी सिर्फ मूल myList वस्तु का उपयोग कर सकते हैं। (मुझे लगता है कि मैं वास्तव में सवाल नहीं
उठाता

6
यह सिर्फ इतना है कि अगर वह myList का संपादन करता है तो वह myEnumrable का संपादन करेगा, लेकिन यदि वह सूची को संपादित करता है तो वह myEnumerable का संपादन नहीं करेगा।
क्रिसडब्ल्यू

15
मत भूलो using System.Linq;या आप ToList ()
जेसन

21

A एक List<T>है IEnumerable<T>, इसलिए वास्तव में, a List<T>को 'कन्वर्ट' करने की कोई आवश्यकता नहीं है IEnumerable<T>। चूंकि a एक List<T>है IEnumerable<T>, आप बस एक List<T>प्रकार के चर को असाइन कर सकते हैंIEnumerable<T>

आसपास का दूसरा तरीका, हर IEnumerable<T>कोई एक List<T>संभोग नहीं है, इसलिए तब आपको ToList()सदस्य विधि को कॉल करना होगा IEnumerable<T>


4
तकनीकी रूप से, ToList System.inq.Enumerable का एक सदस्य तरीका है
Amy B

2
मुझे लगता है कि आप बस IEnumerable को सूची में डाल सकते हैं क्योंकि डेविड कहते हैं कि यह है।
अबशीशेव १४'०

9

A List<T>पहले से ही एक है IEnumerable<T>, इसलिए आप सीधे अपने पर LINQ स्टेटमेंट चला सकते हैंList<T> वैरिएबल ।

यदि आपको LINQ एक्सटेंशन विधियां नहीं दिखती हैं, जैसे OrderBy()मैं अनुमान लगा रहा हूं क्योंकि आपके पास ऐसा नहीं हैusing System.Linq आपके स्रोत फ़ाइल में निर्देश ।

आपको LINQ अभिव्यक्ति परिणाम को List<T>स्पष्ट रूप से वापस करने की आवश्यकता है , हालांकि:

List<Customer> list = ...
list = list.OrderBy(customer => customer.Name).ToList()

"यदि आप ऑर्डरबाय () की तरह LINQ एक्सटेंशन मेथड नहीं देखते हैं" तो यह मेरी समस्या थी, धन्यवाद।
RyPope

5

एक तरफ: ध्यान दें कि मानक LINQ ऑपरेटर्स (पहले के उदाहरण के अनुसार) मौजूदा सूची को नहीं बदलते हैं - list.OrderBy(...).ToList()फिर से ऑर्डर किए गए अनुक्रम के आधार पर एक नई सूची बनाएंगे। हालांकि, एक विस्तार विधि बनाना बहुत आसान है, जो आपको लैम्ब्डा का उपयोग करने की अनुमति देता है List<T>.Sort:

static void Sort<TSource, TValue>(this List<TSource> list,
    Func<TSource, TValue> selector)
{
    var comparer = Comparer<TValue>.Default;
    list.Sort((x,y) => comparer.Compare(selector(x), selector(y)));
}

static void SortDescending<TSource, TValue>(this List<TSource> list,
    Func<TSource, TValue> selector)
{
    var comparer = Comparer<TValue>.Default;
    list.Sort((x,y) => comparer.Compare(selector(y), selector(x)));
}

तो आप का उपयोग कर सकते हैं:

list.Sort(x=>x.SomeProp); // etc

यह मौजूदा सूची को उसी तरह अपडेट List<T>.Sortकरता है जो आमतौर पर करता है।


इस कथन में थोड़ा सुधार: मानक LINQ ऑपरेटर्स मौजूदा सूची को नहीं बदलते हैं; इसके बजाय, वे एक नया IEnumerable बनाते हैं जिसमें उनके कार्य करने के लिए आवश्यक तर्क होते हैं। हालाँकि, इस तर्क को वास्तव में निष्पादित नहीं किया जाता है जब तक कि IEnumerator अनुरोध नहीं किया जाता है।
वोजिस्लाव स्टोजकोविक

@Vojislav - मैं पहले उदाहरण के साथ समाप्त होने के संदर्भ में था ToList- मैं स्पष्ट करूंगा, हालांकि।
मार्क Gravell

1

में परिवर्तित List<T>हो रहा हैIEnumerable<T>

List<T>लागू IEnumerable<T>(और कई अन्य जैसे IList<T>, ICollection<T>) इसलिए पहले से ही IEnumerable में एक सूची वापस बदलने की कोई आवश्यकता नहीं हैIEnumerable<T>

उदाहरण:

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
}

Person person1 = new Person() { Id = 1, Name = "Person 1" };
Person person2 = new Person() { Id = 2, Name = "Person 2" };
Person person3 = new Person() { Id = 3, Name = "Person 3" };

List<Person> people = new List<Person>() { person1, person2, person3 };

//Converting to an IEnumerable
IEnumerable<Person> IEnumerableList = people;

आप Enumerable.AsEnumerable()विधि का भी उपयोग कर सकते हैं

IEnumerable<Person> iPersonList = people.AsEnumerable();

में परिवर्तित IEnumerable<T>हो रहा हैList<T>

IEnumerable<Person> OriginallyIEnumerable = new List<Person>() { person1, person2 };
List<Person> convertToList = OriginallyIEnumerable.ToList();

यह एंटिटी फ्रेमवर्क में उपयोगी है ।


0

स्मृति में दोहराव को रोकने के लिए, पुनर्जीवन यह सुझाव दे रहा है:

List<string> myList = new List<string>();
IEnumerable<string> myEnumerable = myList;
List<string> listAgain = myList as List<string>() ?? myEnumerable.ToList();

.ToList () एक नई अपरिवर्तनीय सूची देता है। इसलिए सूची में परिवर्तन @Tamas Czinege उत्तर में myList को प्रभावित नहीं करता है। यह कम से कम दो कारणों से अधिकांश उदाहरणों में सही है: इससे एक क्षेत्र में दूसरे क्षेत्र (ढीली युग्मन) को प्रभावित करने वाले परिवर्तनों को रोकने में मदद मिलती है, और यह बहुत पठनीय है, क्योंकि हमें संकलक चिंताओं के साथ कोड डिजाइन नहीं करना चाहिए।

लेकिन कुछ उदाहरण हैं, जैसे तंग पाश में होना या एक एम्बेडेड या कम मेमोरी सिस्टम पर काम करना, जहां संकलक के विचारों को ध्यान में रखा जाना चाहिए।

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