Mam klasę, która implementuje IEnumerable
, ale nie implementuje IEnumerable<T>
. Nie mogę zmienić tej klasy i nie mogę zamiast niej użyć innej klasy. Jak zrozumiałem z MSDN LINQ może być używany, jeśli klasa implementujeIEnumerable<T>
. Próbowałem użyć instance.ToQueryable()
, ale nadal nie włącza metod LINQ. Wiem na pewno, że ta klasa może zawierać instancje tylko jednego typu, więc klasa mogłaby zaimplementować IEnumerable<T>
, ale tak po prostu nie jest. Więc co mogę zrobić, aby wykonać zapytanie o tę klasę przy użyciu wyrażeń LINQ?
.net
linq
ienumerable
Bogdan Verbenets
źródło
źródło
Odpowiedzi:
Możesz użyć
Cast<T>()
lub,OfType<T>
aby uzyskać ogólną wersję IEnumerable, która w pełni obsługuje LINQ.Na przykład.
IEnumerable objects = ...; IEnumerable<string> strings = objects.Cast<string>();
Lub jeśli nie wiesz, jaki typ zawiera, zawsze możesz to zrobić:
IEnumerable<object> e = objects.Cast<object>();
Jeśli Twój nieogólny
IEnumerable
zawiera obiekty różnego typu, a interesują Cię tylko np. struny, które możesz zrobić:IEnumerable<string> strings = objects.OfType<string>();
źródło
Tak, może. Wystarczy użyć tej
Cast<T>
funkcji, aby przekonwertować ją na wpisanyIEnumerable<T>
. Na przykład:IEnumerable e = ...; IEnumerable<object> e2 = e.Cast<object>();
Teraz
e2
jestIEnumerable<T>
i może współpracować ze wszystkimi funkcjami LINQ.źródło
Możesz również użyć składni przetwarzania zapytań LINQ, która rzutuje na typ zmiennej zakresu (
item
w tym przykładzie), jeśli typ jest określony: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); }
Efekt jest identyczny z rozwiązaniem @ JaredPar; Aby uzyskać szczegółowe informacje, zobacz 7.16.2.2: Jawne typy zmiennych zakresu w specyfikacji języka C #.
źródło