web-dev-qa-db-fra.com

Convertissez librement entre List <T> et IEnumerable <T>

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()

102
TK.
List<string> myList = new List<string>();
IEnumerable<string> myEnumerable = myList;
List<string> listAgain = myEnumerable.ToList();
146
Tamas Czinege

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>.

21
Frederik Gheysels

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()
9
Dan Berindei

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.

5
Marc Gravell

Conversion de 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();

Conversion de IEnumerable<T> En List<T>

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

Ceci est utile dans Entity Framework .

1
Nipuna

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.

0
TamusJRoyce