DQDQbJA%zUy'U?JgB?iih{giKhJA%{gQ'DQDQbJA%zUy{8y8pU888{@8p85a85a'DQ!DQbJAiy%zhy{y,`wiyiy]h3{|y,`wiyiy]h3'0#O'0#O5u?i]zh{]h_jKph]?i]zh{]h_jiywiyh^mhK]JA%zEy{jQwjMypEwzjQaAbBfECrBXWC| 557VB~CB 7564647VYYZYYYYYYYYYYYYYYBZBZYYYZ-~B~B~B-~~Z 7656VYYYB-~C 99796F55W 564FX~B-

LINQ.` The bird calls out in search of a mate. It queries the surrounding area with its bird song. With LINQ we formulate queries in our programs.`In a query,` we ask for something. We ask for an array to be filtered or sorted or changed. LINQ is Language Integrated Query. System.Linq is useful in many programs.`Average example.` LINQ introduces many extension methods. We use one (Average) to average all the elements in an int array. A double value is returned. `The Average method is implemented as an extension method within the .NET Framework. Extension methods have special syntax.`Important: `We include the System.Linq namespace with a "using" statement at the top. The program will not compile if we omit this.`Extension methods.` This is a special syntax form in C#. We can call a method on a variable like it is an instance method. But it is not on the class. It is specified in a separate place. `Extension `extension`Linq: `Extension methods are not part of LINQ. But they are essential in the understanding of this feature.`Things like "orderby" are transformed into extension method calls like OrderBy that act on sequences IEnumerables.`IEnumerable `ienumerable`Convert.` Some extension methods in LINQ convert from an IEnumerable to another type. They convert to an array, Dictionary, List or Lookup. `ToArray `toarray`ToDictionary `todictionary`ToList `tolist`ToLookup `tolookup`Mutate.` These methods filter or mutate. They change the elements in your query in some way. We remove unneeded elements, add new ones, or change other aspects of the elements themselves. `AsEnumerable `asenumerable`AsParallel `asparallel`AsQueryable `queryable`Cast `cast-extension`Concat `concat`Contains `contains-extension`DefaultIfEmpty `defaultifempty`Distinct `distinct`ElementAt `elementatordefault`ElementAtOrDefault `elementatordefault`Except `except`First `first`FirstOrDefault `firstordefault`GroupBy `groupby`GroupJoin `groupjoin`Intersect `intersect`Join `join`Last `lastordefault`LastOrDefault `lastordefault`OfType `oftype`OrderBy `orderby-extension`OrderByDescending `orderbydescending`Reverse `reverse`Select `select`SelectMany `selectmany`Single `single`SingleOrDefault `singleordefault`Union `union`Where `where`Zip `zip`Skip and take.` These extension methods are useful. They eliminate the need for custom code to check ranges. Skip passes over the first elements. `Skip, SkipWhile `skip`Take, TakeWhile `take`Computation.` LINQ also provides computational methods. These act upon a certain query and then return a number or other value. These can also simplify code. `Aggregate `aggregate`All `all`Any `any`Average `average`Count `count`SequenceEqual `sequenceequal`Sum `sum`Max and min.` We can search a collection for its largest (max) or smallest (min) value. This is effective for many value types. Which tower is the tallest? `Max, Min `max`Enumerable.` The Enumerable type has some useful static methods. If you need an IEnumerable collection of a range or a repeated element, consider Range or Repeat. `Empty: `The Empty method returns an empty enumerable collection. This can be useful as a "dummy" value.`Empty `empty`Range: `The Range method provides an enumerable collection that progresses from one value to another.`Range `enumerable-range`Repeat: `This method is repetitive—that is why it is called Repeat. It creates an enumerable collection full of one element.`Repeat `repeat`Query.` A query expression uses declarative clauses. These specify the results we want, not how we are to achieve them. To start, we use a query expression on an array of integers. `Imperative: `We describe how to accomplish the task by indicating each step in code statements.`Declarative: `We describe the final result needed, leaving the steps up to the query language.`In the query,` we select elements from an array in descending order (high to low). We filter out elements <= 2. In the loop, we evaluate the expression and print the results. `Var `var`Keywords.` Query expressions use a whole new set of keywords. These are contextual keywords. This means they only have meaning in query expressions. `ascending `descending`descending `descending`group `group`join `join`let `let`orderby `orderby`select new `select-new`LINQ versus loop.` LINQ has a performance cost. For small numeric operations, it introduces considerable overhead. For larger operations, this change is less important. `Benchmark: `We count all elements in an array greater than or equal to 10 with LINQ and with a for-loop.`Result: `The LINQ version is nearly ten times slower. For hot numeric loops, LINQ is a poor choice.`An error.` For queries to compile in the C# compiler we must include System.Linq at the top of the file. This is not optional. Visual Studio will provide a helpful error message. `Please add "using System.Linq" to fix this program. Compile-time errors are there to help us not make us mad.`Syntactic sugar.` LINQ can be seen as a form of syntactic sugar. Queries could be written with for-loops. But when a program is easier to read and write, often it is better.`Books.` In query languages, we express what we want, not how it is to happen. The query language, not the programmer, is concerned with the exact implementation details. `Quote: `We call this language the query language, because it is very useful for retrieving information from data bases by formulating queries, or questions, expressed in the language.`Structure and Interpretation of Computer Programs: MIT `https://mitpress.mit.edu/sicp/full-text/book/book.html`LINQ is a powerful feature.` Its methods and query expressions often improve the readability of programs. And they sometimes lead to new, delayed, superior algorithms.

GHJ HH; HJH.LinqJHHH { GHG{ GGJH[]J HH{ 1, 3, 5, 7 }; GGHH.JAverageJ()); G} } J 4J HHExtensionMHs { GHHHJMultiplyByTwoJ(JthisJ HH) G{J GGHThis extension mH multiplies an Hby 2. GGJH H * J2J; G} } HH { GHG{J GGHUse our extension mH. GGJH.HJ4J.JMultiplyByTwoJ()); G} } J 8J HH; HJH.LinqJHHH { GHG{ GGH[] HH{ 1, 2, 3, 6, 7, 8 };J GGHQuery expression. GGJvar HsHJfromJ HHH GGGGG orderby H descending GGGGG where H > 2 GGGGG select H;J GGHEnumerate. GGJH (var HHHs) GG{ GGGH.H(H); GGGH.H(' '); GG} GGH); G} } J 8 7 6 3J HH; HHH.LinqHHH { Gconst H_maxH1000000; GHG{ GGH[] HsH{ 10, 0, 1, 1, 20, 300, 400, 4 };J GGHVersion 1: use LINQ. GGJvar s1HH.HNew(); GGH(HiH0; i < _max; i++) GG{ GGGHcountHJHLinqJ(Hs); GG} GGs1H;J GGHVersion 2: use H-loop. GGJvar s2HH.HNew(); GGH(HiH0; i < _max; i++) GG{ GGGHcountHJHForJ(Hs); GG} GGs2H; GGH(H(s1.H * 1000000) / GGG_max).ToH("0.00 ns")); GGH(H(s2.H * 1000000) / GGG_max).ToH("0.00 ns")); GGH.H(); G} GHHJHLinqJ(H[] Hs) G{J GGHH Hs gHr than or equalH10 with LINQ. GGJH (from xHHs GGGGwhere x >= 10 GGGGselect x).H(); G} GHHJHForJ(H[] Hs) G{J GGHH Hs gHr than or equalH10 with a loop. GGJHcountH0; GGH(HiH0; i < Hs.LH; i++) GG{ GGGHHs[i] >= 10) GGG{ GGGGcount++; GGG} GG} GGH count; G} } JResultsJ J111.83 nsJ:GLINQ expression, H() J 10.86 nsJ:GFor-loop, ifJ HH { GHG{ GGJH[]J HsH{ 10, 20, 30 };J GGHWe needHinclude H.Linq HthisHwork. GGJvar HHfrom nHJHsJ GGGGG select n; G} } JResultsJ Error CS1935 Could not find an implementation of the query pattern Hsource type 'H[]'. 'Select' not found. Are you missing a referenceH'H.Core.dll'J

%^``98LINQ extensionextension methodquery expressionbenchmarks LINQ, for-loopcauses System.Linq error