Funktioniert LINQ mit IEnumerable?

85

Ich habe eine Klasse, die implementiert IEnumerable, aber nicht implementiert IEnumerable<T>. Ich kann diese Klasse nicht ändern und stattdessen keine andere Klasse verwenden. Wie ich aus MSDN verstanden habe, kann LINQ verwendet werden, wenn Klassen implementiert werdenIEnumerable<T> . Ich habe es versucht instance.ToQueryable(), aber es aktiviert immer noch keine LINQ-Methoden. Ich weiß mit Sicherheit, dass diese Klasse nur Instanzen eines Typs enthalten kann, sodass die Klasse sie implementieren kann IEnumerable<T>, aber dies ist einfach nicht der Fall. Was kann ich also tun, um diese Klasse mit LINQ-Ausdrücken abzufragen?

Bogdan Verbenets
quelle
Ohne das Umsetzen der IEnumerable werden anstelle aller linq-Methoden nur 8 Methoden angezeigt: AsQueryable, Cast <>, Equals, GetEnumerator, GetHashCode, GetType, OfType <>, ToString
ShawnFeatherly

Antworten:

133

Sie können eine generische Version einer IEnumerable verwenden Cast<T>()oder OfType<T>abrufen, die LINQ vollständig unterstützt.

Z.B.

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

Oder wenn Sie nicht wissen, welchen Typ es enthält, können Sie immer Folgendes tun:

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

Wenn Ihr Nicht-Generikum IEnumerableObjekte verschiedener Typen enthält und Sie nur an z. die Zeichenfolgen, die Sie tun können:

IEnumerable<string> strings = objects.OfType<string>();
DeCaf
quelle
2
Jeden Tag lerne ich etwas Neues über LINQ. Jeden Tag liebe ich es mehr und mehr.
João Mendes
11

Ja, kann es. Sie müssen nur die Cast<T>Funktion verwenden, um sie in eine Eingabe umzuwandeln IEnumerable<T>. Beispielsweise:

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

Jetzt e2ist ein IEnumerable<T>und kann mit allen LINQ-Funktionen arbeiten.

JaredPar
quelle
3

Sie können auch die Syntax des Abfrageverständnisses von LINQ verwenden, die in den Typ der Bereichsvariablen ( itemin diesem Beispiel) umgewandelt wird, wenn ein Typ angegeben wird:

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);
}

Der Effekt ist identisch mit der Lösung von @ JaredPar. Weitere Informationen finden Sie unter 7.16.2.2: Explizite Bereichsvariablentypen in der C # -Sprachenspezifikation.

TrueWill
quelle