Nasıl dönüştürebilirsiniz List<MyObject>
bir etmek IEnumerable<MyObject>
sonra tekrar ve?
Listede bir dizi LINQ ifadesi çalıştırmak için bunu yapmak istiyorum, örn. Sort()
Yanıtlar:
List<string> myList = new List<string>();
IEnumerable<string> myEnumerable = myList;
List<string> listAgain = myEnumerable.ToList();
using System.Linq;
, yoksa ToList () yapamayacaksın
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>
.
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.Linq
kaynak 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()
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>.Sort
normalde olduğu gibi günceller.
ToList
Yine de açıklayacağım.
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();
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 .
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.