List <T> ve IEnumerable <T> arasında serbestçe dönüştürme


Yanıtlar:


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

30
Bununla birlikte, myEnumarable'ın myList ile aynı nesne örneği olduğuna, ancak listAgain'in myEnumerable ile aynı nesne örneği olmadığına dikkat edin. Ne yapmak istediğinize ve myEnumerable'ın ne olduğuna bağlı olarak, "List <string> listAgain = myEnumerable as List <string>;" daha iyi olabilir.
ChrisW

1
Chrisw: Ah evet, elbette haklısın, ama IEnumerable <T> arayüzü değişmez, bu yüzden bu yönde sorunlara neden olmaz ve geri dönüş , tip güvenliğini sağlayacak bir fonksiyona sahip olduğunuzda sadece kirli hisseder .
Tamas Czinege

1
Orijinal myList nesnesini de kullanabilirsiniz. (Ben gerçekten soru alamadım sanırım)
STH

6
Sadece myList'i düzenlerse, myEnumrable'ı düzenlerdi, ancak listAgain'i düzenlerse o zaman myEnumerable'ımı düzenlemeyecek.
ChrisW

15
Unutma using System.Linq;, yoksa ToList () yapamayacaksın
Jason

21

A List<T>bir olan IEnumerable<T>'dönüştürmek' a gerek yoktur, bu yüzden aslında List<T>bir hiç IEnumerable<T>. A bir List<T>olduğu için IEnumerable<T>, List<T>bir tür değişkenine basitçe a atayabilirsiniz IEnumerable<T>.

Tersi, her IEnumerable<T>bir olduğunu List<T>bu nedenle ardından aramak gerekecek, offcourse ToList()üyesi yöntemini IEnumerable<T>.


4
Teknik olarak ToList, System.Linq.Enumerable'ın bir üye yöntemidir
Amy B

2
David'in söylediği gibi IEnumerable'ı List'e aktarabilirsiniz.
abatishchev

9

A List<T>zaten bir olduğundan IEnumerable<T>, LINQ ifadelerini doğrudan List<T>değişkeninizde çalıştırabilirsiniz .

LINQ uzantı yöntemlerini OrderBy()tahmin ettiğim gibi görmüyorsanız, bunun nedeni using System.Linqkaynak dosyanızda bir yönergenizin olmamasıdır .

List<T>Bununla birlikte , LINQ ifadesi sonucunu açık bir şekilde geri dönüştürmeniz gerekir :

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

"OrderBy () gibi LINQ genişletme yöntemlerini görmüyorsanız" Benim sorunum buydu, teşekkür ederim.
RyPope

5

Bir kenara: Standart LINQ operatörlerinin (önceki örnekte olduğu gibi) mevcut listeyi değiştirmediğini - list.OrderBy(...).ToList()yeniden sıralanan sıraya göre yeni bir liste oluşturacağını unutmayın. Bununla birlikte, lambdaları aşağıdakilerle kullanmanıza izin veren bir uzatma yöntemi oluşturmak oldukça kolaydır 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)));
}

O zaman şunları kullanabilirsiniz:

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

Bu, mevcut listeyi List<T>.Sortnormalde olduğu gibi günceller.


Bu ifadede küçük bir düzeltme: standart LINQ operatörleri mevcut listeyi değiştirmez; bunun yerine, işlerini yapmak için gerekli mantığı içeren yeni bir IEnumerable oluştururlar. Ancak bu mantık, IEnumerator talep edilene kadar yürütülmez.
Vojislav Stojkovic

@Vojislav - ile biten önceki örnek bağlamında anlam ifade ediyordum - ToListYine de açıklayacağım.
Marc Gravell

1

dönüştürme List<T>içinIEnumerable<T>

List<T>uygular IEnumerable<T>(ve diğerleri gibi IList<T>, ICollection<T>) bu nedenle, zaten bir IEnumerable<T>.

Misal:

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()Yöntemi de kullanabilirsiniz

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

dönüştürme IEnumerable<T>içinList<T>

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

Bu, Entity Framework'te kullanışlıdır .


0

Bellekte yinelenmeyi önlemek için, yeniden paylaşma şunu önermektedir:

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

.ToList () yeni bir değişmez liste döndürür. Bu nedenle listAgain'de yapılan değişiklikler @Tamas Czinege'deki myList yanıtını etkilemez. Bu, çoğu durumda en az iki nedenden dolayı doğrudur: Bu, bir alandaki diğer alanı etkileyen değişikliklerin önlenmesine yardımcı olur (gevşek bağlantı) ve derleyici endişeleriyle kod tasarlamamamız gerektiği için çok okunabilir.

Ancak sıkı bir döngüde olmak veya gömülü veya düşük bellekli bir sistemde çalışmak gibi, derleyicinin göz önünde bulundurulması gereken belirli durumlar vardır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.