Tải bản đầy đủ (.pdf) (45 trang)

this site is individual site for ueh students of information management faculty this site provides some students resources of it courses such as computer network data structure and algorithm enterprise resource planning

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (438.53 KB, 45 trang )

<span class='text_page_counter'>(1)</span><div class='page_container' data-page=1>

<b>Chapter 15. Introduction</b>



</div>
<span class='text_page_counter'>(2)</span><div class='page_container' data-page=2>

Objectives



</div>
<span class='text_page_counter'>(3)</span><div class='page_container' data-page=3>

Roadmap



15.1 Understanding the Role of LINQ



15.2 A First Look at LINQ Query Expressions


15.3 LINQ and Generic Collections



15.4 LINQ and Nongeneric Collections




</div>
<span class='text_page_counter'>(4)</span><div class='page_container' data-page=4>

15.1 The Role of LINQ



The LINQ API is an attempt to provide a consistent,



symmetrical manner in which programmers can obtain


and manipulate “data” in the broad sense of the term



LINQ Expressions Are Strongly Typed and Extendable



The Core LINQ Assemblies



 System.Core.dll



 System.Data.Linq.dll


 System.Data.DataSetExtensions.dll


</div>
<span class='text_page_counter'>(5)</span><div class='page_container' data-page=5>

The Role of LINQ



Advantages of LINQ



 For now:


 Dynamically-created string queries



 Doesn't provide compile-time checking


 Native code and non-native code is mixed


 With LINQ


 Static typing


 Compile-time syntax checking


</div>
<span class='text_page_counter'>(6)</span><div class='page_container' data-page=6>

Roadmap




15.1 Understanding the Role of LINQ



15.2 A First Look at LINQ Query Expressions



15.3 LINQ and Generic Collections



15.4 LINQ and Nongeneric Collections



</div>
<span class='text_page_counter'>(7)</span><div class='page_container' data-page=7>

15.2 A First Look at LINQ Query


Expressions




LINQ and Implicitly Typed Local Variables



 Type of the variable induced from expression


 Must include initializer
 Can’t be null. Why not?


 What happens if “var” is a class in scope?
 Works in for loops


<b>var i =</b> <b>5;</b>



<b>var s =</b> <b>"Hello";</b>


<b>var d =</b> <b>1.0;</b>


</div>
<span class='text_page_counter'>(8)</span><div class='page_container' data-page=8>

LINQ Query Expressions



LINQ and Extension Methods



 The Problem: How to add a method to a type you don’t control


and can’t subtype?



 Example: How to add Standard Query Operators to


IEnumerable<T>, without deriving a new interface?


 Solution: Extension methods aren’t really members of the target


type, but the syntax makes them look that way


</div>
<span class='text_page_counter'>(9)</span><div class='page_container' data-page=9>

LINQ Query Expressions



LINQ and Extension Methods




 Not for properties, events, operators


 Currently under consideration


 Equivalent to calling the static method


 Difference from actually extending the class?


 How could we use this for Polynomials?


 Disadvantages?



 Implicitness


</div>
<span class='text_page_counter'>(10)</span><div class='page_container' data-page=10>

LINQ Query Expressions



Creating Extension Methods



 Define a Static Class


 Define a static method whose first argument is an object of type
T


 [System.Runtime.CompilerServices.Extension] attribute on first


parameter tells CLR the method is an Extension


 C# binds the attribute to keyword “this”


 Create a T object, and call the method as if it were a member of
the object


</div>
<span class='text_page_counter'>(11)</span><div class='page_container' data-page=11>

Replacing LINQ Extension Methods



 Extension Methods have lower priority of resolution than type
members



 So if a type has a member with same signature as a LINQ


extension method, the type’s member will be called, and there is
no ambiguity


This is how DLINQ and XLINQ replace the default LINQ



implementations of the Standard Query Operators


<b>class</b> <b>MyList :</b> <b>IEnumerable<int> {</b>


<b>public</b> <b>IEnumerable<int></b> <b>Where(</b>



<b>Func<int,bool></b> <b>filter) {</b>


<b>// LINQ queries on MyList objects will call this</b>
<b>// instead of Sequence.Where()</b>


</div>
<span class='text_page_counter'>(12)</span><div class='page_container' data-page=12>

Lambda Expressions



 Lambda Expressions


 Generalized function syntax


  x . x + 1



 in C# 3.0, have x => x + 1


 From anonymous delegate syntax:


 delegate(int x) { return x + 1;}


 Can have implicitly typed variables


 Can have more than one variable


 Can have expression or statement body



</div>
<span class='text_page_counter'>(13)</span><div class='page_container' data-page=13>

 Lambda expressions


 Can be converted to delegate type


 if parameters and body match


 Participate in type inference


 If expression body, get expression trees


Lambda Expression




<b>delegate</b> <b>R Func<A,R>(A arg);</b>


<b>Func<int,int></b> <b>f1 =</b> <b>x =></b> <b>x +</b> <b>1;</b>


<b>Func<int,double></b> <b>f2 =</b> <b>x =></b> <b>x +</b> <b>1;</b>


</div>
<span class='text_page_counter'>(14)</span><div class='page_container' data-page=14>

Lambda Expression



 Lambda expressions


 Type inference



 If call Select(customers, c => c.Name);


 T, S mapped to appropriate types


<b>public</b> <b>static</b> <b>IEnumerable<S></b> <b>Select<T,S>(</b>


<b>this</b> <b>IEnumerable<T></b> <b>source,</b>


<b>Func<T,S></b> <b>selector)</b>


<b>{</b>



<b>foreach</b> <b>(T element in</b> <b>source)</b>


<b>yield return</b> <b>selector(element);</b>


</div>
<span class='text_page_counter'>(15)</span><div class='page_container' data-page=15>

The Role of Differed Execution



LINQ query expressions are not actually evaluated



until you iterate over their contents



Apply the same LINQ query multiple times to the




</div>
<span class='text_page_counter'>(16)</span><div class='page_container' data-page=16>

The Role of Immediate Execution



To evaluate a LINQ expression from outside the confines



of foreach logic, you are able to call any number of


extension methods defined by the Enumerable type



Extension methods:ToArray<T>,



ToDictionary<TSource,TKey>(), and ToList<T>()




Capture a LINQ query result set in a strongly typed



</div>
<span class='text_page_counter'>(17)</span><div class='page_container' data-page=17>

Roadmap



15.1 Understanding the Role of LINQ



15.2 A First Look at LINQ Query Expressions



15.3 LINQ and Generic Collections



15.4 LINQ and Nongeneric Collections




</div>
<span class='text_page_counter'>(18)</span><div class='page_container' data-page=18>

15.3 LINQ and Generic Collections



LINQ query expressions can also manipulate data within



members of the System.Collections.Generic namespace,


such as the List<T> type



<b>class</b> <b>Car</b>


<b>{</b>


<b>public</b> <b>string</b> <b>PetName =</b> <b>string.Empty;</b>



<b>public</b> <b>string</b> <b>Color =</b> <b>string.Empty;</b>


<b>public</b> <b>int</b> <b>Speed;</b>


<b>public</b> <b>string</b> <b>Make =</b> <b>string.Empty;</b>
<b>}</b>


</div>
<span class='text_page_counter'>(19)</span><div class='page_container' data-page=19>

Classes



System.Collections.Generic classes




 List<ItemType>


 Dictionary<K,V>


 Stack<ItemType>


 Queue<ItemType>


System.Collections.Generic interfaces



 IList<ItemType>



 IDictionary<K,V>


 ICollection<ItemType>


 IEnumerable<ItemType>


 IEnumerator<ItemType>


</div>
<span class='text_page_counter'>(20)</span><div class='page_container' data-page=20>

Applying a LINQ Expression



grabbing items from the List<T> where the Speed




property is greater than 55



<b>static void</b> <b>GetFastCars(List<Car></b> <b>myCars)</b>
<b>{</b>


<b>// Create a query expression.</b>


<b>var fastCars =</b> <b>from c in</b> <b>myCars where c.Speed ></b> <b>55</b> <b>select c;</b>


<b>foreach</b> <b>(var car in</b> <b>fastCars)</b>
<b>{</b>



<b>Console.WriteLine("{0} is going too fast!",</b> <b>car.PetName);</b>


</div>
<span class='text_page_counter'>(21)</span><div class='page_container' data-page=21>

Roadmap



15.1 Understanding the Role of LINQ



15.2 A First Look at LINQ Query Expressions


15.3 LINQ and Generic Collections



15.4 LINQ and Nongeneric Collections



</div>
<span class='text_page_counter'>(22)</span><div class='page_container' data-page=22>

15.4 LINQ and Nongeneric Collections




It is possible to iterate over data contained within



nongeneric collections using the generic


Enumerable.OfType<T>() method



<b>// Extract the ints from the ArrayList.</b>


<b>ArrayList myStuff =</b> <b>new</b> <b>ArrayList();</b>


<b>myStuff.AddRange(new object[] {</b> <b>10,</b> <b>400,</b> <b>8,</b> <b>false,</b> <b>new</b> <b>Car(),</b>



<b>"string data"</b> <b>});</b>


<b>IEnumerable<int></b> <b>myInts =</b> <b>myStuff.OfType<int>();</b>


<b>// Prints out 10, 400, and 8.</b>


</div>
<span class='text_page_counter'>(23)</span><div class='page_container' data-page=23>

Nongeneric Collections



Use the previously defined Car type and import the



System.Collections namespace


<b>static void</b> <b>Main(string[]</b> <b>args)</b>


<b>{</b>


<b>Console.WriteLine("***** LINQ over ArrayList *****\n");</b>


<b>// Here is a nongeneric collection of cars.</b>
<b>ArrayList myCars =</b> <b>new</b> <b>ArrayList() {</b>


<b>new</b> <b>Car{</b> <b>PetName =</b> <b>"Henry",</b> <b>Color =</b> <b>"Silver",</b> <b>Speed =</b> <b>100,</b> <b>Make </b>


<b>=</b> <b>"BMW"},</b>



<b>new</b> <b>Car{</b> <b>PetName =</b> <b>"Daisy",</b> <b>Color =</b> <b>"Tan",</b> <b>Speed =</b> <b>90,</b> <b>Make =</b>


<b>"BMW"},</b>


<b>new</b> <b>Car{</b> <b>PetName =</b> <b>"Mary",</b> <b>Color =</b> <b>"Black",</b> <b>Speed =</b> <b>55,</b> <b>Make =</b>


<b>"VW"},</b>


<b>new</b> <b>Car{</b> <b>PetName =</b> <b>"Clunker",</b> <b>Color =</b> <b>"Rust",</b> <b>Speed =</b> <b>5,</b> <b>Make =</b>


<b>"Yugo"},</b>



</div>
<span class='text_page_counter'>(24)</span><div class='page_container' data-page=24>

Roadmap



15.1 Understanding the Role of LINQ



15.2 A First Look at LINQ Query Expressions


15.3 LINQ and Generic Collections



15.4 LINQ and Nongeneric Collections



15.5 The Internal Representation of LINQ Query Operators



</div>
<span class='text_page_counter'>(25)</span><div class='page_container' data-page=25>

15.5 The Internal Representation of LINQ



Query Operators



Introduced to the process of building query expressions



using various C# query operators (such as from, in,


where, orderby, and select)



C# compiler actually translates these tokens into calls on



various methods of the System.Linq.Enumerable type



Many methods require a generic delegate of type




</div>
<span class='text_page_counter'>(26)</span><div class='page_container' data-page=26>

Query Expressions



 Adds querying to language


 Important for interaction with DB


 Built-in data structures


 Leave query planning to data structure designer


 Implemented using above functionality



 Anonymous types and variables useful


</div>
<span class='text_page_counter'>(27)</span><div class='page_container' data-page=27>

Query Expressions



 As with collections:


 not an interface


 just need to implement the methods


 necessary for backwards compatibility



 methods may be implemented by extension


 Methods named as above


 Any class that implements pattern can be accessed via the new


</div>
<span class='text_page_counter'>(28)</span><div class='page_container' data-page=28>

Building Query Expressions with Query


Operators



Building LINQ expressions using various query operators




(from, in, where, orderby, etc.) is the most common and


most straightforward approach



<b>static void</b> <b>QueryStringWithOperators()</b>
<b>{</b>


<b>Console.WriteLine("***** Using Query Operators *****");</b>


<b>string[]</b> <b>currentVideoGames = {"Morrowind",</b> <b>"BioShock",</b>
<b>"Half Life 2: Episode 1",</b> <b>"The Darkness",</b>


<b>"Daxter",</b> <b>"System Shock 2"};</b>


<b>// Build a query expression using query operators.</b>


<b>var subset =</b> <b>from g in</b> <b>currentVideoGames</b>


<b>where g.Length ></b> <b>6</b> <b>orderby g select g;</b>


</div>
<span class='text_page_counter'>(29)</span><div class='page_container' data-page=29>

Building Query Expressions Using the


Enumerable Type and Lambdas



 Building a LINQ query expression using the methods of the


Enumerable type directly is much more verbose than making use of


the C# query operators


<b>static void</b> <b>QueryStringsWithEnumerableAndLambdas()</b>
<b>{</b>


<b>string[]</b> <b>currentVideoGames = {"Morrowind",</b> <b>"BioShock",</b>
<b>"Half Life 2: Episode 1",</b> <b>"The Darkness",</b>


<b>"Daxter",</b> <b>"System Shock 2"};</b>


<b>// Build a query expression using extension methods</b>
<b>// granted to the Array via the Enumerable type.</b>



<b>var subset =</b> <b>currentVideoGames.Where(game =></b> <b>game.Length ></b> <b>6)</b>


<b>.OrderBy(game =></b> <b>game).Select(game =></b> <b>game);</b>


<b>// Print out the results.</b>


<b>foreach</b> <b>(var game in</b> <b>subset)</b>


<b>Console.WriteLine("Item: {0}",</b> <b>game);</b>


</div>
<span class='text_page_counter'>(30)</span><div class='page_container' data-page=30>

Building Query Expressions Using the




Enumerable Type and Anonymous Methods


<b>static void</b> <b>QueryStringsWithAnonymousMethods()</b>


<b>{</b>


<b>Console.WriteLine("***** Using Anonymous Methods *****");</b>


<b>string[]</b> <b>currentVideoGames = {"Morrowind",</b> <b>"BioShock",</b>
<b>"Half Life 2: Episode 1",</b> <b>"The Darkness",</b>


<b>"Daxter",</b> <b>"System Shock 2"};</b>



<b>// Build the necessary Func<> delegates using anonymous methods.</b>


<b>Func<string,</b> <b>bool></b> <b>searchFilter =</b>


<b>delegate(string</b> <b>game) {</b> <b>return</b> <b>game.Length ></b> <b>6; };</b>


<b>Func<string,</b> <b>string></b> <b>itemToProcess =</b> <b>delegate(string</b> <b>s) {</b>


<b>return</b> <b>s; };</b>


<b>// Pass the delegates into the methods of Enumerable.</b>



<b>var subset =</b> <b>currentVideoGames.Where(searchFilter)</b>


<b>.OrderBy(itemToProcess).Select(itemToProcess);</b>


</div>
<span class='text_page_counter'>(31)</span><div class='page_container' data-page=31>

Building Query Expressions Using the


Enumerable Type and Raw Delegates



<b>class</b> <b>VeryComplexQueryExpression</b>


<b>{</b>



<b>public</b> <b>static void</b> <b>QueryStringsWithRawDelegates()</b>
<b>{</b>


<b>Console.WriteLine("***** Using Raw Delegates *****");</b>


<b>string[]</b> <b>currentVideoGames = {"Morrowind",</b> <b>"BioShock",</b>


<b>"Half Life 2: Episode 1",</b> <b>"The Darkness",</b>


<b>"Daxter",</b> <b>"System Shock 2"};</b>


<b>// Build the necessary Func<> delegates using anonymous methods.</b>



<b>Func<string,</b> <b>bool></b> <b>searchFilter =</b> <b>new</b> <b>Func<string,</b> <b>bool>(Filter);</b>


<b>Func<string,</b> <b>string></b> <b>itemToProcess =</b> <b>new</b>
<b>Func<string,string>(ProcessItem);</b>


<b>// Pass the delegates into the methods of Enumerable.</b>
<b>var subset =</b> <b>currentVideoGames</b>


<b>.Where(searchFilter).OrderBy(itemToProcess).Select(itemToProcess);</b>


<b>// Print out the results.</b>



<b>foreach</b> <b>(var game in</b> <b>subset)</b>


<b>Console.WriteLine("Item: {0}",</b> <b>game);</b>


<b>Console.WriteLine();</b>
<b>}</b>


</div>
<span class='text_page_counter'>(32)</span><div class='page_container' data-page=32>

Internal Representation



Query expressions are created using various C# query


operators




Query operators are simply shorthand notations for invoking


extension methods defined by the System.Linq.Enumerable


type



Many methods of Enumerable require delegates (Func<> in


particular) as parameters



Under C# 2008, any method requiring a delegate parameter


can instead be passed a lambda expression



<sub>Lambda expressions are simply anonymous methods in </sub>




</div>
<span class='text_page_counter'>(33)</span><div class='page_container' data-page=33>

Roadmap



15.1 Understanding the Role of LINQ



15.2 A First Look at LINQ Query Expressions


15.3 LINQ and Generic Collections



15.4 LINQ and Nongeneric Collections



15.5 The Internal Representation of LINQ Query Operators




</div>
<span class='text_page_counter'>(34)</span><div class='page_container' data-page=34>

15.6 Investigating the C# LINQ Query


Operators



<b>Operators</b> <b>Meaning in Life</b>


from, in


Used to define the backbone for any LINQ expression,
which allows you to extract a subset of data from a
fitting container.


where Used to define a restriction for which items to extract


from a container


select Used to select a sequence from the container


join, on, equals, into


</div>
<span class='text_page_counter'>(35)</span><div class='page_container' data-page=35>

Building a New Test Project



Create a new Console Application named



FunWithLinqExpressions




Next, define a trivial Car type



Populate an array with the following Car objects within



</div>
<span class='text_page_counter'>(36)</span><div class='page_container' data-page=36>

<b>class</b> <b>Car</b>


<b>{</b>


<b>public</b> <b>string</b> <b>PetName =</b> <b>string.Empty;</b>


<b>public</b> <b>string</b> <b>Color =</b> <b>string.Empty;</b>



<b>public</b> <b>int</b> <b>Speed;</b>


<b>public</b> <b>string</b> <b>Make =</b> <b>string.Empty;</b>


<b>public override</b> <b>string</b> <b>ToString()</b>
<b>{</b>


<b>return</b> <b>string.Format("Make={0}, Color={1}, Speed={2}, PetName={3}",</b>


<b>Make,</b> <b>Color,</b> <b>Speed,</b> <b>PetName);</b>
<b>}</b>



<b>}</b>


<b>static void</b> <b>Main(string[]</b> <b>args)</b>
<b>{</b>


<b>Console.WriteLine("***** Fun with Query Expressions *****\n");</b>


<b>// This array will be the basis of our testing...</b>


<b>Car[]</b> <b>myCars =</b> <b>new</b> <b>[] {</b>


<b>new</b> <b>Car{</b> <b>PetName =</b> <b>"Henry",</b> <b>Color =</b> <b>"Silver",</b> <b>Speed =</b> <b>100,</b> <b>Make =</b> <b>"BMW"},</b>



<b>new</b> <b>Car{</b> <b>PetName =</b> <b>"Daisy",</b> <b>Color =</b> <b>"Tan",</b> <b>Speed =</b> <b>90,</b> <b>Make =</b> <b>"BMW"},</b>


<b>new</b> <b>Car{</b> <b>PetName =</b> <b>"Mary",</b> <b>Color =</b> <b>"Black",</b> <b>Speed =</b> <b>55,</b> <b>Make =</b> <b>"VW"},</b>


<b>new</b> <b>Car{</b> <b>PetName =</b> <b>"Clunker",</b> <b>Color =</b> <b>"Rust",</b> <b>Speed =</b> <b>5,</b> <b>Make =</b> <b>"Yugo"},</b>


<b>new</b> <b>Car{</b> <b>PetName =</b> <b>"Hank",</b> <b>Color =</b> <b>"Tan",</b> <b>Speed =</b> <b>0,</b> <b>Make =</b> <b>"Ford"},</b>


<b>new</b> <b>Car{</b> <b>PetName =</b> <b>"Sven",</b> <b>Color =</b> <b>"White",</b> <b>Speed =</b> <b>90,</b> <b>Make =</b> <b>"Ford"},</b>


<b>new</b> <b>Car{</b> <b>PetName =</b> <b>"Mary",</b> <b>Color =</b> <b>"Black",</b> <b>Speed =</b> <b>55,</b> <b>Make =</b> <b>"VW"},</b>



<b>new</b> <b>Car{</b> <b>PetName =</b> <b>"Zippy",</b> <b>Color =</b> <b>"Yellow",</b> <b>Speed =</b> <b>55,</b> <b>Make =</b> <b>"VW"},</b>


<b>new</b> <b>Car{</b> <b>PetName =</b> <b>"Melvin",</b> <b>Color =</b> <b>"White",</b> <b>Speed =</b> <b>43,</b> <b>Make =</b> <b>"Ford"}</b>
<b>};</b>


</div>
<span class='text_page_counter'>(37)</span><div class='page_container' data-page=37>

Basic Selection Syntax



Ordering of the operators is critical



var result = from item in container select item;




<b>static void</b> <b>BasicSelection(Car[]</b> <b>myCars)</b>
<b>{</b>


<b>// Get everything.</b>


<b>Console.WriteLine("All cars:");</b>


<b>var allCars =</b> <b>from c in</b> <b>myCars select c;</b>


<b>foreach</b> <b>(var c in</b> <b>allCars)</b>
<b>{</b>



<b>Console.WriteLine(c.ToString());</b>
<b>}</b>


</div>
<span class='text_page_counter'>(38)</span><div class='page_container' data-page=38>

Obtaining Subsets of Data



To obtain a specific subset from a container, use the



<i>where operator</i>



<i>var result = from item in container where Boolean</i>



<i>expression select item;</i>




<b>static void</b> <b>GetSubsets(Car[]</b> <b>myCars)</b>
<b>{</b>


<b>// Now get only the BMWs.</b>


<b>var onlyBMWs =</b> <b>from c in</b> <b>myCars where c.Make ==</b>


<b>"BMW"</b> <b>select c;</b>


</div>
<span class='text_page_counter'>(39)</span><div class='page_container' data-page=39>

Projecting New Data Types




The compiler defines a only property and a



read-only backing field for each specified name



Project new forms of data from an existing data source



<b>var makesColors =</b> <b>from c in</b> <b>myCars select new</b> <b>{c.Make,</b>


<b>c.Color};</b>


<b>foreach</b> <b>(var o in</b> <b>makesColors)</b>
<b>{</b>



</div>
<span class='text_page_counter'>(40)</span><div class='page_container' data-page=40>

Reversing Result Sets



Using the generic Reverse<T>() method of the



<i>Enumerable type</i>



<b>static void</b> <b>ReversedSelection(Car[]</b> <b>myCars)</b>
<b>{</b>


<b>// Get everything in reverse.</b>



<b>Console.WriteLine("All cars in reverse:");</b>


<b>var subset = (from c in</b> <b>myCars select </b>
<b>c).Reverse<Car>();</b>


<b>foreach</b> <b>(Car c in</b> <b>subset)</b>
<b>{</b>


<b>Console.WriteLine("{0} is going {1} </b>
<b>MPH",</b> <b>c.PetName,</b> <b>c.Speed);</b>


</div>
<span class='text_page_counter'>(41)</span><div class='page_container' data-page=41>

Sorting Expressions




 A query expression can take an orderby operator to sort items in the subset by a
specific value


 To view the results in a descending order, simply include the descending operator


</div>
<span class='text_page_counter'>(42)</span><div class='page_container' data-page=42>

Example


1. static void OrderedResults(Car[] myCars)


2. {



3. // Order all the cars by PetName.


4. var subset = from c in myCars orderby c.PetName select c;
5. Console.WriteLine("Ordered by PetName:");


6. foreach (Car c insubset)


7. {


8. Console.WriteLine(c.ToString());


9. }



10. // Now find the cars that are going less than 55 mph,
11. // and order by descending PetName


12. subset = from c in myCars


13. where c.Speed > 55 orderby c.PetName descending select c;


14. Console.WriteLine("\nCars going faster than 55, ordered by PetName:");
15. foreach (Car c insubset)


16. {



17. Console.WriteLine(c.ToString());


18. }


</div>
<span class='text_page_counter'>(43)</span><div class='page_container' data-page=43>

Finding Differences



 <b>obtaining a result set that determines the differences between </b>
<i><b>two IEnumerable<T> compatible containers</b></i>


static void GetDiff()
{



List<string> myCars = new List<String>
{ "Yugo", "Aztec", "BMW"};


List<string> yourCars = new List<String>
{ "BMW", "Saab", "Aztec" };


var carDiff =(from c in myCars select c)


.Except(from c2 in yourCars select c2);


Console.WriteLine("Here is what you don't have, but I do:");



foreach (string s in carDiff)


Console.WriteLine(s); // Prints Yugo.


</div>
<span class='text_page_counter'>(44)</span><div class='page_container' data-page=44>

Summary



LINQ is a set of related technologies that attempts to



provide a single, symmetrical manner to interact with


diverse forms of data




LINQ query expressions can return any number of result



sets, it is common to make use of the var keyword to


represent the underlying data type



LINQ query operators are simply shorthand notations for



</div>
<span class='text_page_counter'>(45)</span><div class='page_container' data-page=45>

References



Books:



</div>


<!--links-->

×