Comment puis-je convertir un List<MyObject>
En un IEnumerable<MyObject>
, Puis de nouveau?
Je souhaite le faire afin d'exécuter une série d'instructions LINQ sur la liste, e. g. Sort()
List<string> myList = new List<string>();
IEnumerable<string> myEnumerable = myList;
List<string> listAgain = myEnumerable.ToList();
Un List<T>
Est un IEnumerable<T>
, Il n'est donc pas nécessaire de "convertir" un List<T>
En un IEnumerable<T>
. Étant donné que List<T>
Est un IEnumerable<T>
, Vous pouvez simplement affecter un List<T>
À une variable de type IEnumerable<T>
.
Inversement, tous les IEnumerable<T>
Ne sont pas des cours List<T>
. Vous devrez donc appeler la méthode ToList()
member de IEnumerable<T>
.
Un List<T>
Est déjà un IEnumerable<T>
, Vous pouvez donc exécuter des instructions LINQ directement sur votre variable List<T>
.
Si vous ne voyez pas les méthodes d'extension LINQ telles que OrderBy()
, je suppose que c'est parce que vous n'avez pas de directive using System.Linq
Dans votre fichier source.
Vous devez reconvertir explicitement le résultat de l'expression LINQ en un List<T>
:
List<Customer> list = ...
list = list.OrderBy(customer => customer.Name).ToList()
De plus: notez que les opérateurs LINQ standard (comme dans l'exemple précédent) ne modifient pas la liste existante - list.OrderBy(...).ToList()
créeront une nouvelle liste basée sur la séquence réordonnée. Il est cependant assez facile de créer une méthode d’extension qui vous permet d’utiliser lambdas avec 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)));
}
Ensuite, vous pouvez utiliser:
list.Sort(x=>x.SomeProp); // etc
Ceci met à jour la liste existante de la même manière que List<T>.Sort
fait habituellement.
List<T>
En IEnumerable<T>
List<T>
Implémente IEnumerable<T>
(Et beaucoup d'autres tels que IList<T>, ICollection<T>
), Il n'est donc pas nécessaire de reconvertir une liste en IEnumerable, car elle contient déjà un IEnumerable<T>
.
Exemple:
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;
Vous pouvez également utiliser la méthode Enumerable.AsEnumerable()
IEnumerable<Person> iPersonList = people.AsEnumerable();
IEnumerable<T>
En List<T>
IEnumerable<Person> OriginallyIEnumerable = new List<Person>() { person1, person2 };
List<Person> convertToList = OriginallyIEnumerable.ToList();
Ceci est utile dans Entity Framework .
Pour éviter les doublons en mémoire, le resharper suggère ceci:
List<string> myList = new List<string>();
IEnumerable<string> myEnumerable = myList;
List<string> listAgain = myList as List<string>() ?? myEnumerable.ToList();
.ToList () renvoie une nouvelle liste immuable. Ainsi, les modifications apportées à listAgain n'affectent pas myList dans la réponse de @Tamas Czinege. Ceci est correct dans la plupart des cas pour deux raisons au moins: cela permet d'éviter les changements dans un domaine qui affectent l'autre (couplage lâche) et il est très lisible, car nous ne devrions pas concevoir de code avec des préoccupations de compilateur.
Mais il existe certains cas, comme être dans une boucle serrée ou travailler sur un système embarqué ou à faible mémoire, où les considérations du compilateur doivent être prises en compte.