Dla jakiej domeny problemowej jest stworzony LINQ?

12

Za każdym razem, gdy widzę pytanie opublikowane na przepełnieniu stosu na C #, widzę co najmniej jedną lub dwie odpowiedzi, które rozwiązują problem z LINQ. Zwykle ludzie o bardzo wysokiej reputacji wydają się używać LINQ jak profesjonaliści.

Moje pytanie brzmi: do jakiej domeny problemowej należy użyć LINQ?

Również na marginesie: Czy są jakieś cele, w których należy tego unikać? Czy rozmiar zestawu danych wpływa na wydajność zapytań LINQ?

użytkownik1816120
źródło
1
LINQ służy do tworzenia zapytań do grafów obiektowych. Jest to Language Integrated Query - pozwala na zapytania i manipulowanie kolekcjami.
Oded
1
jest to prawdopodobnie pytanie, które można zamknąć, ponieważ może tam być dobre pytanie, na jakie problemy linq jest odpowiedni
jk.
1
Linq jest deklaratywny. Stwierdzasz „co” chcesz bez określania „jak” to się robi. W przypadku linq oznacza to, że możesz użyć zapytań, aby określić, co chcesz. Kod deklaratywny może być krótszy i łatwiejszy do zrozumienia dla niektórych problemów.
mike30

Odpowiedzi:

16

LINQ został zaprojektowany przede wszystkim w celu umożliwienia czysto funkcjonalnych zapytań i transformacji sekwencji danych (zauważysz, że wszystkie rozszerzenia LINQ biorą delegatów Func, ale nie delegatów akcji). W związku z tym najczęstszym przypadkiem pętli, która nie pasuje bardzo dobrze do LINQ, jest przypadek, w którym chodzi o niejasne funkcjonalne skutki uboczne, np.

foreach(var x in list) Console.WriteLine(x);

Aby lepiej korzystać z LINQ, po prostu ćwicz go.

Za każdym razem, gdy masz zamiar napisać komendę forlub foreachpętlę, aby zrobić coś z kolekcją, zatrzymaj się, zastanów się, czy to dobrze pasuje do LINQ (tj. Nie chodzi tylko o wykonanie akcji / efektu ubocznego na elementach), a jeśli tak, zmuś się do napisania używając LINQ.

Możesz także foreachnajpierw napisać wersję, a następnie przepisać ją na wersję LINQ.

Jak wskazuje svick, LINQ powinien polegać na zwiększeniu czytelności programu. Zwykle jest w tym dobry, ponieważ podkreśla raczej intencję kodu niż mechanizmu; jednak jeśli okaże się, że nie można uczynić zapytań bardziej czytelnymi niż zwykła pętla, nie krępuj się i trzymaj się pętli.

Jeśli potrzebujesz ćwiczeń do ćwiczenia, większość funkcjonalnych ćwiczeń z programowaniem ładnie odwzoruje na LINQ, np. 99 problemów (szczególnie pierwszych 20 lub więcej) lub euler projektu .

jk.
źródło
Być może będę musiał teraz usunąć to pytanie. Moderator skomentował, że nie nadaje się dla społeczności. Jeśli uważasz inaczej, proszę powiedz mi.
user1816120,
1
Dodałbym, że jeśli przepiszesz go do LINQ, a oryginał jest nadal bardziej czytelny, zachowaj oryginał i usuń wersję LINQ. Czasami LINQ po prostu nic nie dodaje.
sick
@svick w teorii tak, nie jestem pewien, czy mogę wymyślić jakieś przykłady;)
jk.
1
@jk. Na przykład ReSharper czasami oferuje konwersję mojej pętli do LINQ za pomocą Aggregate(). Myślę, że przez większość czasu pętla jest bardziej czytelna.
sick
@svick to prawdopodobnie problem z tym, do czego jesteś przyzwyczajony, choć przyznam, że agregacja to niezdarna nazwa fold
jk.
1

Aby odpowiedzieć na edytowane pytanie: krótko mówiąc, warto skorzystać z LINQ, ilekroć trzeba zaimplementować funkcję „zapytania” (to właśnie oznacza Q w LINQ). Określenie dokładnej domeny jest trudne, ale znacznie upraszcza różnorodne zadania związane z wyodrębnianiem i manipulowaniem danymi z kolekcji.

Aby nieco rozwinąć, wiele funkcji zapytań zostało wprowadzonych bezpośrednio do języka (a raczej różnych implementatorów LINQ), więc rzeczy takie jak agregacje, porządkowanie, grupowanie, filtrowanie, projekcje, łączenia (i wiele innych) są obsługiwane dla ty. Rozwiązania oparte na LINQ są również zwykle znacznie krótsze niż gdybyś wdrożył je „ręcznie”, a także znacznie lepiej zakomunikował swoje zamiary.

Prostym przykładem, który często pomaga przekazać moc LINQ, jest wyświetlenie zawartości katalogu pogrupowanego według rozszerzeń. Przeprowadź typową implementację imperatywną w swojej głowie - na początku będzie wiele szczegółów implementacji. Być może użyjemy a Dictionary<String, List<String>>do indeksowania plików według rozszerzenia. Oczywiście będziemy musieli sprawdzić, czy klucz już istnieje, utworzyć instancję listy, dodać do niej itp. Może to wyglądać następująco:

Dictionary<string, List<string>> fileGroups = new Dictionary<string, List<string>>();

foreach (string file in Directory.GetFiles(Environment.CurrentDirectory))
{
    string extension = Path.GetExtension(file).ToLower();

    if (!fileGroups.ContainsKey(extension))
    {
        fileGroups[extension] = new List<string>();
    }

    fileGroups[extension].Add(file);
}

Rozważ odpowiednik LINQ:

var query = from file in Directory.GetFiles(Environment.CurrentDirectory)
            group file by Path.GetExtension(file).ToLower();

Zauważ, że samo zapytanie ma tylko 2 wiersze, z pewnością krótsze niż jakiekolwiek bezwzględnie konieczne rozwiązanie. Jest również dość czytelny; stosunek sygnału do szumu jest wyższy niż w pierwszym rozwiązaniu. W przypadku nowych użytkowników LINQ wyniki tego zapytania byłyby wyświetlane w następujący sposób:

foreach (var fileGroup in query)
{
    Console.WriteLine(String.Format("*** Files with extension: {0}", group.Key));

    foreach (string file in fileGroup)
    {
        Console.WriteLine(file);
    }
}

W przypadku bardziej złożonych przykładów różnice zwykle stają się jeszcze większe (na przykład po prostu pogrupuj według wielu pól). Podsumowując, LINQ rozwiązuje wiele codziennych problemów z kwerendami danych w sposób, który jest często krótszy i bardziej opisowy. To wymaga niewielkiego kosztu nauki składni i technologii, ale korzyści znacznie przewyższają negatywne.

Daniel B.
źródło
Czy klasyfikujesz mapę lub składasz jako „zapytania”? Naprawdę nie, ale myślę, że mógłbym to zobaczyć. Zwykle pomyślałbym o agregacie w wyniku obliczeń, a nie o „zapytaniu”
Jimmy Hoffa,
@JimmyHoffa Mam na myśli głównie zastosowanie obliczeń do podstawowej kolekcji, niekoniecznie samego obliczenia. Ale w mojej analogii są prawdopodobnie luki, które mają być ilustracyjne, a nie w 100% poprawne.
Daniel B
@ JimmyHoffa nie, ale nie jestem pewien, czy istnieje ścisła definicja tego, od czego ma zaczynać się zapytanie
jk.
0

Z czasem opracowano różne języki dla różnych typów źródeł danych, na przykład SQL dla relacyjnych baz danych i XQuery dla XML. Dlatego programiści musieli nauczyć się nowego języka zapytań dla każdego typu źródła danych lub formatu danych, który muszą obsługiwać. LINQ upraszcza tę sytuację, oferując spójny model pracy z danymi w różnych źródłach i formatach danych. W zapytaniu LINQ zawsze pracujesz z obiektami. więcej informacji na stronie http://msdn.microsoft.com/en-us/library/bb397906.aspx

Rabbil
źródło
Dokładnie LINQ to abstrakcyjny interfejs API do pracy z kolekcjami. Kilka ważnych korzyści: używając C # dostajesz STATIC! Weryfikacja twoich zapytań i przekształceń
AndreasScheinert