LINQ funziona con IEnumerable?


87

Ho una classe che implementa IEnumerable, ma non implementa IEnumerable<T>. Non posso cambiare questa classe e non posso usare un'altra classe al posto di essa. Come ho capito da MSDN, LINQ può essere utilizzato se la classe implementaIEnumerable<T> . Ho provato a usare instance.ToQueryable(), ma ancora non abilita i metodi LINQ. So per certo che questa classe può contenere istanze di un solo tipo, quindi la classe potrebbe implementare IEnumerable<T>, ma semplicemente non lo fa. Quindi cosa posso fare per interrogare questa classe utilizzando espressioni LINQ?


Senza eseguire il cast di IEnumerable, invece di tutti i metodi linq vedrai solo 8 metodi: AsQueryable, Cast <>, Equals, GetEnumerator, GetHashCode, GetType, OfType <>, ToString
ShawnFeatherly

Risposte:


136

È possibile usare Cast<T>()o OfType<T>per ottenere una versione generica di un oggetto IEnumerable che supporta completamente LINQ.

Per esempio.

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

Oppure se non sai che tipo contiene puoi sempre fare:

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

Se il tuo non generico IEnumerablecontiene oggetti di vario tipo e sei interessato solo ad es. le stringhe che puoi fare:

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

2
Ogni giorno imparo qualcosa di nuovo su LINQ. Ogni giorno lo adoro sempre di più.
João Mendes

11

Sì, può. Hai solo bisogno di usare la Cast<T>funzione per convertirlo in un file digitato IEnumerable<T>. Per esempio:

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

Now e2è un IEnumerable<T>e può funzionare con tutte le funzioni LINQ.


3

È inoltre possibile utilizzare la sintassi di comprensione delle query di LINQ, che esegue il cast al tipo della variabile di intervallo ( itemin questo esempio) se viene specificato un tipo:

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'effetto è identico alla soluzione di @ JaredPar; vedere 7.16.2.2: Tipi di variabili con intervallo esplicito nella specifica del linguaggio C # per i dettagli.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.