Zapytanie LINQ vs metody LINQ

Wszyscy chyba zdają sobie sprawę z tego, jakim dobrodziejstwem jest LINQ, które pojawiło się dosyć dawno, wraz z .NET 3.0 3.5. Jak wiadomo LINQ oferuje trochę nowych słów kluczowych oraz trochę metod – i tu pojawia się pytanie  – czym różni się zapis za pomocą słów kluczowych od zapisu „metodowego”? Szczególnie interesujące zdaje się być to, czy któryś z zapisów powoduje jakiś narzut wydajnościowy.

Nie będę budował napięcia i od razu odpowiem – query syntax w zasadzie nie różni się niczym od zapisu za pomocą extension methods. W praktyce, zapytanie zapisane za pomocą słów kluczowych jest tłumaczone podczas procesu kompilacji na coś, co CLR świetnie rozumie – metody. Microsoft, tak jak wielu programistów, preferuje zapis „zapytaniowy” nad „metodowym” ze względu na czytelność. Moim zdaniem jest to sprawa mocno dyskusyjna, dla mnie często dużo bardziej czytelniejsze jest używanie extension methods. Ponadto, niestety nie wszystko zapisywalne za pomocą extension methods da się zapisać za pomocą słów kluczowych, ale o tym za moment w przykładach.

Przykład 1

int[] numbers = { 5, 10, 8, 3, 6, 12 };

IEnumerable numQuery1 =
    from num in numbers
    where num % 2 == 0
    orderby num
    select num;

Taki kod równoważny jest (i jednocześnie tłumaczony w procesie kompilacji na następujący):

IEnumerable numQuery2 = numbers.Where(num => num % 2 == 0).OrderBy(n => n);

Czy ten drugi nie wydaje się Wam czytelniejszy? ;) Nietrudno jednak stworzyć przykład w którym query syntax będzie bardziej wymowne.

Przykład 2

var personQuery1 = from person in people
                   let fullname = person.Name + " " + person.Surname
                   select new { Name = fullname, Age = person.Age };

var personQuery2 = people
                   .Select(person => new { Name = person.Name + " " + person.Surname, Age = person.Age });

W pierwszej linijce widzimy jak przydatne (dla czytelności) jest słowo kluczowe let pozwalające na tymczasową definicję nowej zmiennej (więcej o słówku let tu i tu na blogu Maćka Aniserowicza). Zapis za pomocą extension methods nie jest już taki ładny (choć to też zapewne sprawa gustu). Ostatni przykład zaprezentuje nam, że nie wszystko da się zrobić za pomocą query syntax.

Przykład 3

int[] numbers = { 5, 10, 8, 3, 6, 12 };
var nums = numbers.Skip(3).Take(2).ToList();

Efektu wywołania takich metod nie otrzyma się za pomocą zapytania.

Podsumowanie

Wszystko co da się napisać za pomocą query syntax da się zapisać za pomocą extension methods. Odwrotnie już tak niestety nie jest. Często zapis za pomocą słów kluczowych jest dużo czytelniejszy (szczególnie przy używaniu let, group, join), natomiast metody dają nam szersze możliwości. Wybór więc powinien zależeć od osobistego stylu i zdania na temat tego, co jest bardziej wymownie. Nieważne jednak czy korzystasz z metod, czy z zapytań, powinieneś robić to świadomie, aby nie tracić na wydajności – polecam przeczytać drugi z linków do blogu Maćka powyżej.