Odpowiedzi:
List<string> myList = new List<string>();
IEnumerable<string> myEnumerable = myList;
List<string> listAgain = myEnumerable.ToList();
using System.Linq;
albo nie będziesz w stanie ToList ()
A List<T>
jest IEnumerable<T>
, więc w rzeczywistości nie ma potrzeby „konwertowania” a List<T>
na IEnumerable<T>
. Ponieważ a List<T>
jest an IEnumerable<T>
, możesz po prostu przypisać a List<T>
do zmiennej typu IEnumerable<T>
.
Z drugiej strony nie każdy IEnumerable<T>
jest List<T>
offcourse, więc będziesz musiał wywołać ToList()
metodę składową IEnumerable<T>
.
A List<T>
już jest IEnumerable<T>
, więc możesz uruchamiać instrukcje LINQ bezpośrednio na List<T>
zmiennej.
Jeśli nie widzisz metod rozszerzenia LINQ, jak OrderBy()
zgaduję, to dlatego, że nie masz using System.Linq
dyrektywy w pliku źródłowym.
Musisz jednak przekonwertować wynik wyrażenia LINQ z powrotem na List<T>
jawnie, chociaż:
List<Customer> list = ...
list = list.OrderBy(customer => customer.Name).ToList()
Poza tym: Zwróć uwagę, że standardowe operatory LINQ (zgodnie z wcześniejszym przykładem) nie zmieniają istniejącej listy - list.OrderBy(...).ToList()
utworzą nową listę na podstawie ponownie uporządkowanej sekwencji. Tworzenie metody rozszerzającej, która pozwala na używanie lambd z 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)));
}
Następnie możesz użyć:
list.Sort(x=>x.SomeProp); // etc
Spowoduje to zaktualizowanie istniejącej listy w taki sam sposób, jak List<T>.Sort
zwykle.
ToList
- jednak wyjaśnię.
List<T>
doIEnumerable<T>
List<T>
implements IEnumerable<T>
(i wiele innych, takich jak IList<T>, ICollection<T>
), dlatego nie ma potrzeby konwertowania listy z powrotem na IEnumerable, ponieważ jest to już plik IEnumerable<T>
.
Przykład:
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;
Możesz także użyć Enumerable.AsEnumerable()
metody
IEnumerable<Person> iPersonList = people.AsEnumerable();
IEnumerable<T>
doList<T>
IEnumerable<Person> OriginallyIEnumerable = new List<Person>() { person1, person2 };
List<Person> convertToList = OriginallyIEnumerable.ToList();
Jest to przydatne w Entity Framework .
Aby zapobiec powielaniu w pamięci, Resharper sugeruje, że:
List<string> myList = new List<string>();
IEnumerable<string> myEnumerable = myList;
List<string> listAgain = myList as List<string>() ?? myEnumerable.ToList();
.ToList () zwraca nową niezmienną listę. Tak więc zmiany w listAgain nie mają wpływu na myList w odpowiedzi @Tamas Czinege. W większości przypadków jest to poprawne z co najmniej dwóch powodów: Pomaga to zapobiec zmianom w jednym obszarze wpływającym na inny obszar (luźne sprzężenie) i jest bardzo czytelne, ponieważ nie powinniśmy projektować kodu z problemami kompilatora.
Ale są pewne przypadki, takie jak bycie w ciasnej pętli lub praca w systemie osadzonym lub o małej ilości pamięci, w których należy wziąć pod uwagę kwestie związane z kompilatorem.