Antworten:
List<string> myList = new List<string>();
IEnumerable<string> myEnumerable = myList;
List<string> listAgain = myEnumerable.ToList();
using System.Linq;
oder du wirst nicht in der Lage sein, ToList ()
A List<T>
ist ein IEnumerable<T>
, also besteht eigentlich keine Notwendigkeit, a List<T>
in ein umzuwandeln IEnumerable<T>
. Da a ein List<T>
ist IEnumerable<T>
, können Sie a einfach List<T>
einer Variablen vom Typ zuweisen IEnumerable<T>
.
Umgekehrt ist nicht jeder IEnumerable<T>
ein List<T>
Offcourse, daher müssen Sie die ToList()
Member-Methode von aufrufen IEnumerable<T>
.
A List<T>
ist bereits ein IEnumerable<T>
, sodass Sie LINQ-Anweisungen direkt für Ihre List<T>
Variable ausführen können .
Wenn Sie die LINQ-Erweiterungsmethoden nicht so sehen, wie OrderBy()
ich vermute, liegt das daran, dass using System.Linq
Ihre Quelldatei keine Direktive enthält.
Sie müssen das Ergebnis des LINQ-Ausdrucks jedoch List<T>
explizit wieder in ein Ergebnis konvertieren :
List<Customer> list = ...
list = list.OrderBy(customer => customer.Name).ToList()
Nebenbei: Beachten Sie, dass die Standard-LINQ-Operatoren (wie im vorherigen Beispiel) die vorhandene Liste nicht ändern. Sie list.OrderBy(...).ToList()
erstellen eine neue Liste basierend auf der neu geordneten Reihenfolge. Es ist jedoch ziemlich einfach, eine Erweiterungsmethode zu erstellen, mit der Sie Lambdas verwenden können mit 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)));
}
Dann können Sie verwenden:
list.Sort(x=>x.SomeProp); // etc
Dadurch wird die vorhandene Liste auf die gleiche Weise aktualisiert , wie dies List<T>.Sort
normalerweise der Fall ist.
ToList
- ich werde es jedoch klarstellen.
List<T>
inIEnumerable<T>
List<T>
implementiert IEnumerable<T>
(und viele andere wie IList<T>, ICollection<T>
), daher besteht keine Notwendigkeit, eine Liste zurück in IEnumerable zu konvertieren, da es bereits eine IEnumerable<T>
.
Beispiel:
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;
Sie können auch die Enumerable.AsEnumerable()
Methode verwenden
IEnumerable<Person> iPersonList = people.AsEnumerable();
IEnumerable<T>
inList<T>
IEnumerable<Person> OriginallyIEnumerable = new List<Person>() { person1, person2 };
List<Person> convertToList = OriginallyIEnumerable.ToList();
Dies ist in Entity Framework nützlich .
Um Doppelarbeit im Speicher zu vermeiden, schlägt resharper Folgendes vor:
List<string> myList = new List<string>();
IEnumerable<string> myEnumerable = myList;
List<string> listAgain = myList as List<string>() ?? myEnumerable.ToList();
.ToList () gibt eine neue unveränderliche Liste zurück. Änderungen an listAgain wirken sich also nicht auf myList in der Antwort von @Tamas Czinege aus. Dies ist in den meisten Fällen aus mindestens zwei Gründen richtig: Dies verhindert Änderungen in einem Bereich, die sich auf den anderen Bereich auswirken (lose Kopplung), und ist sehr gut lesbar, da wir keinen Code mit Compiler-Bedenken entwerfen sollten.
Es gibt jedoch bestimmte Fälle, z. B. in einer engen Schleife oder bei der Arbeit an einem eingebetteten System oder einem System mit wenig Arbeitsspeicher, bei denen Compiler-Überlegungen berücksichtigt werden sollten.