2009-01-23 28 views
99

के बीच स्वतंत्र रूप से परिवर्तित करें मैं List<MyObject> को IEnumerable<MyObject> पर फिर से कैसे परिवर्तित कर सकता हूं और फिर वापस आ सकता हूं?सूची <T> और आईनेमेरेबल <T>

मैं सूची में LINQ कथन की एक श्रृंखला चलाने के लिए ऐसा करना चाहता हूं, ई। जी। Sort()

+0

यह इस प्रश्न में शामिल है http://stackoverflow.com/questions/31708/how-can-i-convert-ienumerablet-to-listt-in-c – John

उत्तर

141
List<string> myList = new List<string>(); 
IEnumerable<string> myEnumerable = myList; 
List<string> listAgain = myEnumerable.ToList(); 
+29

सावधान रहें कि मेरा अनन्य एक ही ऑब्जेक्ट उदाहरण है myList, लेकिन listAgain एक ही ऑब्जेक्ट उदाहरण नहीं है जैसा कि मेरे अनन्य है। आप जो करना चाहते हैं उसके आधार पर और मेरा अनन्य क्या है, "सूची listAgain = myEnumerable सूची के रूप में;" बेहतर हो सकता है। – ChrisW

+1

क्रिसव: ओह हाँ, आप बिल्कुल सही हैं, लेकिन आईनेमेरेबल इंटरफ़ेस अपरिवर्तनीय है, इसलिए इससे उस दिशा में समस्याएं नहीं आतीं और वापस कास्टिंग * गंदे * महसूस होती है जब आपके पास कोई ऐसा कार्य होता है जो प्रकार की सुरक्षा का ख्याल रखता है। –

+1

आप मूल मूल सूची का उपयोग भी कर सकते हैं। (मुझे लगता है कि मुझे वास्तव में सवाल नहीं मिलता है) – sth

5

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

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 साथ lambdas उपयोग करने के लिए अनुमति देता है बनाने के लिए किया जाता है जिस तरह से List<T>.Sort आमतौर पर करता है।

+0

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

+0

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

21

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

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

+4

तकनीकी रूप से, ToList System.Linq.Enumerable –

+2

का सदस्य तरीका है, मुझे लगता है कि आप केवल सूची पर IENumerable डाले जा सकते हैं क्योंकि डेविड कहते हैं कि यह है। – abatishchev

9

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

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

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

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

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

0

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

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

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

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

0

List(T) कक्षा 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; 

लेकिन IEnumerable से कन्वर्ट करने के लिए सूची के लिए एक वैध परिदृश्य

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

यह Entity Framework में उपयोगी है।

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