Czy Linq ma oszałamiający wpływ na programistów .NET?

36

Wielu z nas zaczęło widzieć to zjawisko w jQuery około rok temu, kiedy ludzie zaczęli pytać, jak zrobić absolutnie szalone rzeczy, takie jak odzyskiwanie ciągu zapytania za pomocą jQuery . Różnica między biblioteką (jQuery) a językiem (JavaScript) jest najwyraźniej zatracona przez wielu programistów i skutkuje tym, że tam, gdzie nie jest to konieczne, powstaje wiele nieodpowiedniego, skomplikowanego kodu.

Może to tylko moja wyobraźnia, ale przysięgam, że zaczynam dostrzegać wzrost liczby pytań, w których ludzie proszą o zrobienie podobnie szalonych rzeczy z Linq, takich jak znajdowanie zakresów w posortowanej tablicy . Nie mogę się pogodzić z tym, jak całkowicie niewłaściwe są rozszerzenia Linq do rozwiązania tego problemu, ale co ważniejsze, fakt, że autor po prostu założył, że idealne rozwiązanie wymagałoby Linq bez myślenia o tym (o ile wiem). Wygląda na to, że powtarzamy historię, tworząc nową generację programistów .NET, którzy nie potrafią odróżnić języka (C # / VB.NET) od biblioteki (Linq).

Co jest odpowiedzialne za to zjawisko? Czy to tylko szum? Tendencje sroka? Czy Linq zyskał reputację jako forma magii, w której zamiast pisać kod, wystarczy wypowiedzieć właściwą inkantację? Nie jestem zadowolony z tych wyjaśnień, ale tak naprawdę nie mogę wymyślić nic innego.

Co ważniejsze, czy to naprawdę problem, a jeśli tak, jaki jest najlepszy sposób, aby pomóc oświecić te osoby?

Aaronaught
źródło
6
+1 dla „zakładał, że idealne rozwiązanie wymagałoby Linq bez myślenia o tym”. To naprawdę poza mną.
Jaco Pretorius
1
Linq jest wolny ...
2
@Pierre: Na jakiej podstawie wysunąłeś to roszczenie?
Aaronaught
5
@Mason: To absolutnie okropny test porównawczy napisany przez kogoś, kto wyraźnie nie wie, co robią. Benchmarking w kleszczach? Notacja węgierska? A wersja Linq nawet nie robi tego samego, próbuje iterować każdy wynik zamiast zatrzymać się na początku. Nie wspominając o tym, że cała przesłanka jest głupia, jak to przypadkowo omawiano w dzisiejszym gorącym pytaniu .
Aaronaught
3
Nawiasem mówiąc, @Mason, Linq ma wbudowane wiele optymalizacji. Dla prawie każdej metody, którą można zoptymalizować, najpierw szuka interfejsu obsługującego zoptymalizowaną metodę. W przypadku innych metod opartych na zestawach, takich jak equijoins, tworzy tabele skrótów. Nie optymalizuje kodu dla ciebie, ale nie spowoduje też spowolnienia kodu; większość rzeczywistych udokumentowanych spowolnień w świecie rzeczywistym wynika z lambdas / zamknięć niezależnych od Linq.
Aaronaught

Odpowiedzi:

52

Dzieje się tak, ponieważ programowanie jest zasadniczo trudne. Wymaga dużo logicznej, ustrukturyzowanej myśli w taki sposób, że wiele osób po prostu nie wie, jak to zrobić. (Lub po prostu nie da rady, w zależności od tego, kogo słuchasz).

Rzeczy takie jak LINQ i jQuery znacznie ułatwiają niektóre typowe zadania związane z manipulowaniem danymi. To wspaniałe dla tych z nas, którzy wiedzą, co robimy, ale niefortunnym efektem ubocznym jest to, że obniża pasek. Ułatwia to osobom, które nie mają pojęcia, co robią, aby zacząć pisać kod i sprawić, by wszystko działało. A kiedy wpadną w rzeczywistość i znajdą coś fundamentalnie trudnego, na co nie pasują ich proste techniki na wysokim poziomie abstrakcji, gubią się, ponieważ nie rozumieją platformy, na której zbudowana jest ich biblioteka.

Twoje pytanie jest trochę na właściwej drodze, ale podobnie jak odwieczna kontrowersja dotycząca brutalnych gier wideo „zmieniających dzieci w przemoc”, ma kierunek odsyłacza do tyłu. Proste techniki programowania nie powodują, że programiści są głupi; po prostu przyciągają głupców do programowania. I naprawdę niewiele można na to poradzić.

Mason Wheeler
źródło
30
+1 za „Proste techniki programowania nie powodują, że programiści są głupi; po prostu przyciągają głupców do programowania”.
Steven Evers,
1
Jedną wielką zaletą LINQ jest to, że pozwala mi prototypować rozwiązanie w sposób funkcjonalny. Potem, gdy mam rozwiązanie wolne od błędów, mogę użyć go jako stanowiska testowego dla zoptymalizowanej wersji imperatywnej. Jeśli zadanie jest wystarczająco proste, jak zastosowanie jednego filtra, nawet nie będę się tym przejmować.
ChaosPandion
5
Nadal wątpię, czy LINQ przyciąga niekompetentnych programistów - z tego, co widziałem, wydaje się, że jest to jedna z najtrudniejszych koncepcji dla początkujących - ale, jak dotąd, wydaje się to najlepsza odpowiedź.
Aaronaught
1
Powinieneś umieścić prawa autorskie do tego ostatniego zdania. Dobrze powiedziane, proszę pana.
AJ Johnson
1
Zabawny. Dla mnie LINQ nie jest koncepcją szczególnie łatwą do opanowania. Jeśli robisz coś subtelnego, bardzo szybko musisz przestać myśleć o kierownicy i zacząć rozumieć przekładnię. Patrzę na ciebie Lamdas!
Brian MacKay,
13

Dla mnie to nowe zjawisko związane z zabawkami. Wydaje się coś nowego (LINQ), a teraz każdy programista chce się tym bawić.

Widzą LINQ jako młotek, a każdy problem to gwóźdź. Kogo to obchodzi, jeśli łatwiej jest to zrobić w inny sposób? LINQ musi być odpowiedzią! Tak jak wtedy, gdy wszyscy używali XML do WSZYSTKIEGO! Plik konfiguracyjny? XML. Przechowywanie danych? XML. Itd itd

PSU_Kardi
źródło
5
Nie chcę tutaj rozpoczynać debaty XML, ale warto zauważyć, że XML jest w obu przypadkach dobry. Nie zawsze jest to optymalne - jeśli pliki konfiguracyjne nie muszą mieć struktury, KVP są lepsze, a jeśli zgodność między aplikacjami nie jest wymagana, to format binarny jest wyraźnie lepszy do przechowywania / serializacji. Ale nie sądzę, że XML jest tak świetnym przykładem, ponieważ zwykle był używany w obszarach, w których był jedynie nieoptymalny, a nie całkowicie nieodpowiedni.
Aaronaught
4
+1: Rozciągnij swoje narzędzia, aby zobaczyć, ile problemów można wbić w kształt gwoździa podczas nauki technologii.
Steven Evers,
+1: Inne przykłady tego rodzaju magicznego młota to jQuery (jak wspomniano w pytaniu) i wyrażenia regularne. Nie chodzi o to, że te rzeczy są złe, w rzeczywistości są naprawdę przydatne, ale nie są odpowiedzią na wszystko.
Tim Goodman,
14
Myślę, że analogia „LINQ to młotek, a każdy problem jest gwoździem”, przesuwa go nieco za daleko. Powiedziałbym, że LINQ jest tak dobrym młotem, że gdy duża część twojej pracy wymaga gwoździ, możesz wpaść w rowek i nie zauważyć, że właśnie wbiłeś śrubę. Nawet jeśli nie jesteś złym programistą.
Carson63000,
@Aaronaught: Z drugiej strony użycie XML z długimi nazwami pól wydawało mi się nieoptymalne do transmisji danych za pomocą niskiej przepustowości i nie do końca niezawodnych łączy radiowych. Z drugiej strony tak też myślałem o projekcie bazy danych tego produktu.
David Thornley,
10

Myślę, że LINQ oferuje naprawdę dobrą okazję w języku C # w rozwiązywaniu problemów przy użyciu bardziej funkcjonalnego podejścia. Nie powinniśmy odrzucać nowego stylu rozwiązywania problemów tylko dlatego, że mamy już coś, co działa.

Wychodząc z dużego tła SQL, lubię mieć możliwość korzystania z logiki opartej na zestawie w moim C #, aby lepiej opisać cel moich operacji.

To mówi; kontekst jest królem i wszystko może być nadużywane.

dotjosh
źródło
Kto zwalnia? Cały czas używam Linq, martwię się tylko o liczbę przypadków, w których widzę ludzi używających go (lub próbujących go używać) w przypadku problemów, które są wyraźnie iteracyjne i nie oparte na zestawie.
Aaronaught,
Jestem bardzo przyzwyczajony do prób rozwiązywania problemów, które musiały być napisane w języku SQL i do tego celu używam logiki opartej na zestawie zamiast kursorów. Nadużycie narzędzi zawsze się zdarza, ale myślę, że przynajmniej jeśli napiszą słaby kod LINQ zamiast słabego kodu proceduralnego, kolejna wersja .NET będzie mogła przynajmniej łatwiej go zrównoleglić.
dotjosh
2

LINQ i jQuery to najnowsze „zabawki”, a programiści uwielbiają pokazywać, jak mogą robić rzeczy przy użyciu najnowszych rzeczy.

Dan Diplo
źródło
Zgadzam się z tym stwierdzeniem. Nie jestem pewien, czy to wyjaśnia to szczególne zjawisko. Ludzie, którzy zadają te pytania, nie wydają się typem popisywania się - chociaż pomogłoby to wyjaśnić, dlaczego inni programiści próbują odpowiedzieć na zadane pytania zamiast zalecać rozsądne podejście.
Aaronaught
@Aaronaught - Tak, myślę, że myślałem więcej o tym, dlaczego ludzie odpowiadają na pytania, stosując takie podejście.
Dan Diplo,
2

Jeśli właściwie używasz Linq i rozumiesz to pod maską, znajdziesz wiele nowych, najnowocześniejszych technik programowania.

Jeśli więc głęboko zastanawiasz się nad ulepszeniami, twierdzę, że dzięki temu jesteś lepszym programistą. To, czy dany programista faktycznie to robi, czy nie, nie jest winą Linq.

Ten sam argument można wysunąć dla odwzorowań obiektowo-relacyjnych. Czy ktoś naprawdę pisze już surowe zapytania SQL względem tabel bazy danych? :)

Robert Harvey
źródło
10
Hej, piszę surowy SQL ... wącham
Aaronaught
2
Surowy SQL jest najlepszym wyborem, jeśli wiesz, co robisz.
Fosco,
1
+1 za argument „czyni cię lepszym programistą”. Zrozumienie linq, a zwłaszcza metod, które go obsługują, zdecydowanie poprawiło moje zrozumienie niektórych bardzo pomocnych koncepcji programowania.
John M Gant,
1
Myślę, że ktoś obraził się na ORM vs. surowy komentarz SQL. To nie byłem ja; Używam obu, i zrozumiałem, że to spostrzeżenie.
Aaronaught
1
Nigdy nie ufałbym moim złożonym zapytaniom do bazy danych do bzdur, które pisze ORM: W porządku dla prostych rzeczy, ale ugh do raportowania zapytań typu. Znów, w rękach kogoś, kto wie, co robią, ORM jest dobrą rzeczą, w rękach kogoś, kto jest zbyt leniwy, aby zrozumieć bazy danych, katastrofa przed nami.
HLGEM
1

Niektóre z tych szalonych rzeczy są spowodowane tym, że ludzie używają niewłaściwego młotka, inni dlatego, że budują naprawdę elegancki super młot, ale natrafili na dziwny szczegół, który należy pokonać.

Na przykład, jeśli pojawi się pytanie o użycie linq do wygenerowania dynamicznego linq do użycia przeciwko niedynamicznemu linq dziewięć razy na dziesięć, osoba jest albo ciekawa, czy to możliwe, albo szczeka na niewłaściwe drzewo, ale jest kilka rzeczy, które możesz rozwiązać w ten sposób, które są trudne do tego stopnia, że ​​nierozsądne jest rozwiązanie w inny sposób.

Takie pytania zadaję w dwóch częściach:

  1. czy można to zrobić, a jeśli tak, to jak by to wyglądało
  2. czy należy to zrobić, czy istnieje ryzyko lub lepsza alternatywa

Przekonałem się, że prawie zawsze robię je w tej kolejności. Odpowiada na pytanie, a także pomaga w lepszym wyjaśnieniu potencjalnych alternatyw.

Rachunek
źródło
0

Nie wiem o jakimkolwiek odrętwiającym wpływie na umysły programistów, ale spójrz tutaj na wpływ zdezorientowanych narzędzi / języków na stawki. Mów o obniżeniu poprzeczki!

Pete Wilson
źródło
0

Zgadzam się z Masonem Wheelerem. Jednak próba rozwiązania https://stackoverflow.com/questions/3762202/get-range-of-integers-with-linq nie jest wcale szalona, działając na „sekwencji”. Problem polega na tym, że iteratory Java i .Net nie obsługują wszystkich 3 operacji: bieżącej wartości, następnej wartości i przejścia do następnej. Clojure może zrobić wszystkie 3 i podejrzewam, że w Clojure łatwiej to zrobić poprawnie. Python ma również wspólne procedury i chcę spróbować to złamać. http://clojure.org/sequences http://www.try-clojure.org/

W rzeczywistości, jeśli wejście jest sekwencją nieskończoną, taką jak http://oeis.org/A007401 , wtedy leniwy jest jedynym sposobem.

Praca
źródło
„Linq” niekoniecznie oznacza „iteratory” ani „leniwy” niekoniecznie - w rzeczywistości większość Linq naprawdę dotyczy drzewek ekspresyjnych. Możesz łatwo, jeśli chcesz, zaimplementować własny agregat o wartości 3 lub N z zamknięciem i niezbyt dużo kodu w C #. Problem pojawia się, gdy ludzie nie mają pojęcia, jak to zrobić, a nawet jak zacząć, i po prostu szukają magicznej inkantacji, która żyje w System.Linqprzestrzeni nazw.
Aaronaught
@Aaronaught ... '' „Linq” nie oznacza „iteratorów” ani „leniwych” koniecznie ”- no cóż, Linq może wyglądać jak SQL, ale ten cukier składniowy kompiluje się w rzeczywisty kod IL, który, jeśli nie zostanie skompilowany , wyglądałby równorzędnie z kilkoma połączonymi IEnumerable [<T>]. Te rzeczy są leniwe i używają liczników, które w innych językach byłyby nazywane iteratorami. Ale tak, problem polega na tym, że LINQ sprawia, że ​​kodowanie wygląda na łatwe i niewykwalifikowane spróbuj. Niektórzy nadal mogą zostać przyzwoitymi programistami. Jeśli C # jest ich pierwszym językiem i są całkowitymi noobami, to mają do czynienia z dużym językiem.
Job
Jasne, Linq do obiektów (nie Linq do SQL, Linq do Entities, Linq do DataSet lub jakiejkolwiek innej gałęzi Linq) opiera się na iteratorach i odroczonej realizacji, ale to wszystko pod maską. Bloki iteratora i yieldinstrukcja istniały przed Linq, podobnie jak delegaci. Zamknięcia pojawiły się w tym samym wydaniu co Linq, ale niewiele czystych operacji „Linq” faktycznie wymaga przechwytywania zmiennych lokalnych. Pytanie „Jak mogę zrobić [opis całkowicie iteracyjnej operacji / funkcji] za pomocą Linq?” zdradza głęboką nieznajomość zarówno samego Linq (co ma to zrobić), jak i samego języka.
Aaronaught