LINQ fonctionne-t-il avec IEnumerable?


87

J'ai une classe qui implémente IEnumerable, mais ne l'implémente pas IEnumerable<T>. Je ne peux pas changer cette classe, et je ne peux pas utiliser une autre classe à la place. Comme je l'ai compris de MSDN, LINQ peut être utilisé si la classe implémenteIEnumerable<T> . J'ai essayé d'utiliser instance.ToQueryable(), mais cela n'active toujours pas les méthodes LINQ. Je sais avec certitude que cette classe peut contenir des instances d'un seul type, donc la classe pourrait implémenter IEnumerable<T>, mais ce n'est tout simplement pas le cas. Alors, que puis-je faire pour interroger cette classe à l'aide d'expressions LINQ?


Sans lancer le IEnumerable, au lieu de toutes les méthodes linq, vous ne verrez que 8 méthodes: AsQueryable, Cast <>, Equals, GetEnumerator, GetHashCode, GetType, OfType <>, ToString
ShawnFeatherly

Réponses:


134

Vous pouvez utiliser Cast<T>()ou OfType<T>pour obtenir une version générique d'un IEnumerable qui prend entièrement en charge LINQ.

Par exemple.

IEnumerable objects = ...;
IEnumerable<string> strings = objects.Cast<string>();

Ou si vous ne savez pas quel type il contient, vous pouvez toujours faire:

IEnumerable<object> e = objects.Cast<object>();

Si votre non-générique IEnumerablecontient des objets de différents types et que vous n'êtes intéressé que par ex. les chaînes que vous pouvez faire:

IEnumerable<string> strings = objects.OfType<string>();

2
Chaque jour, j'apprends quelque chose de nouveau sur LINQ. Chaque jour, je l'aime de plus en plus.
João Mendes

11

Oui il peut. Il vous suffit d'utiliser la Cast<T>fonction pour le convertir en fichier typé IEnumerable<T>. Par exemple:

IEnumerable e = ...;
IEnumerable<object> e2 = e.Cast<object>();

Maintenant e2est un IEnumerable<T>et peut fonctionner avec toutes les fonctions LINQ.


3

Vous pouvez également utiliser la syntaxe de compréhension de requête de LINQ, qui convertit le type de la variable de plage ( itemdans cet exemple) si un type est spécifié:

IEnumerable list = new ArrayList { "dog", "cat" };

IEnumerable<string> result =
  from string item in list
  select item;

foreach (string s in result)
{
    // InvalidCastException at runtime if element is not a string

    Console.WriteLine(s);
}

L'effet est identique à la solution de @ JaredPar; voir 7.16.2.2: Types de variables de plage explicites dans la spécification du langage C # pour plus de détails.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.