2013-07-15 10 views
6

Jakiś czas temu pracowałem nad dość poskręcanym projektem - mogłem napisać kod tylko w jednym zakresie, a później został on umieszczony w funkcji C# (przez inny moduł).Czy można używać Linq i lambdas bez uwzględniania przestrzeni nazw System.Linq?

Mogłem używać tylko przestrzeni nazw, które zostały zadeklarowane wcześniej (nie miałem na nie wpływu) i mogłem używać tylko zmiennych z zakresu, w którym pracowałem. Z tego powodu nie byłem w stanie zmienić nagłówków i dołączonych bibliotek .

Problem pojawił się, gdy chciał działać na zbiorach generycznych - Nie mogłem używać ani wyrażeń lambda, ani LINQ - Ja po prostu nie mógł umieścić using System.Linq;, ponieważ nie miałem dostępu do nagłówka pliku.

Musiałem zrobić tylko prostą rzecz i łatwo było zarządzać bez LINQ lub lambda. Jednak później zastanawiałem się, co by się stało, gdybym musiał użyć niektórych bardziej złożonych operacji na IEnumerable. Z tego pochodzi moje pytanie:

Czy można używać LINQ lub lambdas bez zmiany nagłówka pliku i dodawania nowych przestrzeni nazw?

Załóżmy, że mamy List<int> _Numbers = new List<int>();. Niech wypełni się pewnymi liczbami. Teraz chcę wybrać wszystkie liczby parzyste z tego.

Z using System.Linq; w nagłówku, rozwiązanie jest oczywiste:

List<int> _NewList = _Numbers.Where(n => n % 2 == 0).ToList(); 

lub

List<int> _NewList = (from _Number in _Numbers where _Number % 2 == 0 select _Number).ToList(); 

Ale bez LINQ włączone, w jaki sposób można to osiągnąć? Moje pierwsze przypuszczenie byłoby coś takiego:

List<int> _NewList = System.Linq. // ??? What to add here? 

Zdaję sobie sprawę, że problem jest dość egzotyczne, i to bardzo niezwykłe, aby przejść w ten sposób, ale jestem po prostu ciekawy i znalazłem żadnych informacji na ten temat walizka.

+1

'System.Linq.Enumerable.Where (_NewList, n => n% 2 == 0)' –

+0

@nsinreal - dzięki, właśnie tego szukałem. Dodaj to jako odpowiedź, a oznaczysz ją jako poprawną;) –

+0

Możesz także dołączyć instrukcje "using" w deklaracji przestrzeni nazw klasy. Czy to wciąż jest poza zakresem, do którego masz dostęp? – Sam

Odpowiedz

15

Bez dyrektywy using metody takie jak .Where, .Select nie zostaną rozwiązane. Oznacza to, że LINQ część językowa nie będzie działać. Trzeba by w nim kodu długiego ręki (i do tyłu!):

List<int> _NewList = System.Linq.Enumerable.ToList(
    System.Linq.Enumerable.Where(_Numbers, _Number => _Number % 2 == 0) 
); 

Zauważ, że to staje się zwiększenie skomplikowane dla dłuższych przykładów z grupami, Zamówienia, „niech” s, przyłącza itd. O ile nie robisz czegoś dość proste, byłoby wskazane, aby znaleźć sposób, aby dodać dyrektywę using.

Należy jednak pamiętać, że jeśli _Numbers jest List<T>, można po prostu użyć (na tym jednym przykładzie):

List<int> _NewList = _Numbers.FindAll(_Number => _Number % 2 == 0); 
+0

Dzięki, wyjaśniłem wiele. Wiem o FindAll(), ale o ile mi wiadomo, działa tylko z List, a ja szukałem bardziej uniwersalnego sposobu. –

2

Niezbyt jasne, dlaczego nie może uzyskać dostępu do pliku „nagłówek”, ale jeśli problem, że nie można wpisać na początku pliku using dirrective, ty może nadal używać pełnej nazwy kwalifikowanej typu, takich jak:

System.Linq.Enumerable(...) 

Aby to zadziałało, musisz oczywiście dołączyć również poprawne referencje.

Jeśli nie o to prosisz, wyjaśnij.

+1

Nie mogłem uzyskać dostępu do nagłówka pliku, to był problem z APi, z którym pracowałem. Wiem, że mogę dodać System.Linq. w zakresie, ale nie wiedziałem, jak dalej ją ocenić. –

3

można napisać taki kod:

System.Linq.Enumerable.Where(_NewList, n => n % 2 == 0) 

Ale należy uważać, : jeśli twoja klasa implementuje interfejs IQueryable<T>, powyższy kod wykona pracę, ale wolniej.

System.Linq.Queryable.Where(_NewList, n => n % 2 == 0) 

Ponieważ IQueryable jest sposób wytwarzania C# w innym języku DSL, jak SQL. W innych warunkach, twój serwer SQL może wybrać potrzebne elementy tak szybko, jak tylko może. Ale jeśli pracujesz z IEnumerable lub System.Linq.Enumerable, nie ma optymalizacji po stronie serwera, dostaniesz pełną listę elementów, wszystkie zostaną załadowane do pamięci i przefiltrowane w pamięci.

Powiązane problemy