Wynikiem wyrażenia zapytania jest zapytanie, a nie wykonanie zapytania.
Eric Lippert,
6
Aby uzyskać mniej informacji, zobacz zaakceptowaną odpowiedź na to pytanie .
Daniel,
9
Z pewnością możesz pomyśleć o tytule, który faktycznie podsumowuje pytanie.
Matt Ball,
2
Moje przypuszczenie co do głosów przeciwnych (do tej pory 6, nie moich) jest takie, że uważają tytuł pytania za zbyt ogólny, aby był dobrym pytaniem. Ale widząc liczbę głosów za i stając się głównym pytaniem tygodnia w biuletynie, nie sądzę, żebyś musiał się tym zbytnio przejmować.
Zapytanie jest faktycznie wykonywane podczas iteracji zmiennej zapytania, a nie podczas tworzenia zmiennej zapytania. Nazywa się to odroczonym wykonaniem.
Istnieje inne wykonanie o nazwie Immediate Query Execution , które jest przydatne do buforowania wyników zapytania. Z Suprotim Agarwal ponownie:
Aby wymusić natychmiastowe wykonanie zapytania, które nie generuje wartości pojedynczej, można wywołać metodę ToList(), ToDictionary(), ToArray(), Count(), Average()lub Max()w kwerendzie lub zmiennej kwerendy. Są to tak zwane operatory konwersji, które umożliwiają wykonanie kopii / migawki wyniku, a dostęp jest możliwy tyle razy, ile chcesz, bez konieczności ponownego wykonywania zapytania.
Jeśli chcesz, aby wynik był 2,4,6, użyj .ToList():
varlist=newList<int>{1,2,4,5,6};var even =list.Where(m => m%2==0).ToList();list.Add(8);foreach(var i in even){Console.WriteLine(i);}
Count (), Max (), Avg (), Sum () i prawdopodobnie inne metody, które wymagają uwzględnienia całej listy, również powodują ocenę zapytania.
Kenned
1
Często myślałem o, powiedzmy, „filterList” jako zmiennej, a nie „filterList ()” jako metodzie - chodzi o to, że za każdym razem, gdy chcesz przefiltrować listę, zamiast wywoływać metodę, będziesz ją powtarzał. Może być interesującą, choć niezwykłą i być może niedoskonałą pod względem wydajności metodą robienia rzeczy.
Katana314,
4
@Sebastian - W nawiązaniu do komentarza @ Kenned za, .First(), .FirstOrDefault(), .Single()a .SingleOrDefault()także wywołać ocenę zapytania.
Scotty.NET,
4
zadziwiające, jak otrzymałeś odpowiedź w mniej niż 30 sekund: D
MC
2
@MC Nie wiem, dlaczego zadajesz to pytanie. Nie udzielono jednocześnie pełnej odpowiedzi. Był kilkakrotnie redagowany.
Atish Dipongkor - MVP
11
Stało się tak z powodu odroczonego wykonania, co oznacza, że obliczenie wyrażenia nie jest wykonywane, dopóki nie jest potrzebne gdzieś. To poprawia wydajność, jeśli dane są zbyt duże.
Możesz to zniwelować, ponieważ może to również oznaczać, że twoje drogie wyliczenie jest wykonywane wiele razy. W takim przypadku możesz nawet stracić wydajność.
Grimace of Despair,
0
Powodem tego jest odroczone wykonanie wyrażenia lambda. Zapytanie jest wykonywane po rozpoczęciu iteracji w pętli foreach.
Z technicznego punktu widzenia jest to odroczone wykonanie iteratora , a nie lambda .
D Stanley,
0
W przypadku korzystania z IEnumerable <> uzyskanego z LINQ jest tworzona tylko klasa Enumerator, a iteracja rozpoczyna się tylko wtedy, gdy używasz jej w jakimś spacerze.
Otrzymujesz ten wynik z powodu odroczonego wykonania, co oznacza, że wynik nie jest w rzeczywistości oceniany do momentu pierwszego dostępu.
Aby było to bardziej zrozumiałe, po prostu dodaj 10 do listy na końcu swojego snipeta i wydrukuj ponownie, nie otrzymasz 10 na wyjściu
varlist=newList<int>{1,2,4,5,6};var even =list.Where(m => m%2==0).Tolist();list.Add(8);foreach(var i in even){Console.WriteLine(i);}//new*list.Add(10);foreach(var i in even){Console.WriteLine(i);}
Naprawdę tego próbowałeś? Dostaję się 10na wyjściu.
Mark Hurd,
dobry chwyt @MarkHurd tak nie dodano .ToList (). edytował post teraz powinien dać oczekiwany wynik. Moje oczekiwanie to wyrażenie jest oceniane tylko wtedy, gdy używasz zmiennej var po raz pierwszy, ale wygląda na to, że jest ona oceniana za każdym razem
Odpowiedzi:
Dane wyjściowe są
2,4,6,8
spowodowane odroczonym wykonaniem .Istnieje inne wykonanie o nazwie Immediate Query Execution , które jest przydatne do buforowania wyników zapytania. Z Suprotim Agarwal ponownie:
Jeśli chcesz, aby wynik był
2,4,6
, użyj.ToList()
:źródło
.First()
,.FirstOrDefault()
,.Single()
a.SingleOrDefault()
także wywołać ocenę zapytania.Stało się tak z powodu odroczonego wykonania, co oznacza, że obliczenie wyrażenia nie jest wykonywane, dopóki nie jest potrzebne gdzieś. To poprawia wydajność, jeśli dane są zbyt duże.
źródło
Powodem tego jest odroczone wykonanie wyrażenia lambda. Zapytanie jest wykonywane po rozpoczęciu iteracji w pętli foreach.
źródło
W przypadku korzystania z IEnumerable <> uzyskanego z LINQ jest tworzona tylko klasa Enumerator, a iteracja rozpoczyna się tylko wtedy, gdy używasz jej w jakimś spacerze.
źródło
Otrzymujesz ten wynik z powodu odroczonego wykonania, co oznacza, że wynik nie jest w rzeczywistości oceniany do momentu pierwszego dostępu.
Aby było to bardziej zrozumiałe, po prostu dodaj 10 do listy na końcu swojego snipeta i wydrukuj ponownie, nie otrzymasz 10 na wyjściu
źródło
10
na wyjściu.8
żadnego wyjścia.