Download - Think in linq
![Page 1: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/1.jpg)
Think in LINQ
Introduction to LINQ to Objects
Sudipta Mukherjee
![Page 2: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/2.jpg)
What shall we talk about?
• Why bother about LINQ?• What’s the origin?• How it works?• Introduction to LINQPad• Some LINQ Operators • Demos• Q & A
Slides are designed for self study at a later
stage also.
So if it seems really long. That’s ok.
Disclaimer
![Page 3: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/3.jpg)
Why bother to learn LINQ ? What can it do for us?
![Page 4: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/4.jpg)
One more step close to conceptWhile you are
expressing your intent by loops you are not only telling
what you want done, but you are giving
painful detail of how you want it done. So it is very difficult for the compiler to emit
high performance code using multiple
processors.
In LINQ you tell WHAT you want, not HOW you want it get
done.
This makes for compilers happy and it can make the code
parallel by using multiple processors
![Page 5: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/5.jpg)
It can query anythingXML/JSON
Database
Objects
What have you!
LINQ
XPath SQL/No-SQL
Loop/If/Else Something
![Page 6: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/6.jpg)
It’s about time we care
• Computer processor speed is stagnated• We won’t get faster processor• We will get more of them• Need Parallelism• Functional approach is good for parallel processing as that’s side-effect free.
![Page 7: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/7.jpg)
Where did it came from? Who are the people behind it?When did it become part of .NET ? Where are we going with this ?
![Page 8: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/8.jpg)
Key people and their talks about LINQ
Erik Meijer Anders Hejlsberg Talk
Talk
![Page 9: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/9.jpg)
When was LINQ born?
2008 / VS 2008
Roslyn / Compiler-as-a-Service Shipping with C# 5.0
![Page 10: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/10.jpg)
Where are we going?
• Asynchronous apps is the future
• Roots of LINQ gave us a new language
![Page 11: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/11.jpg)
Paradigm Shift?
• C# is bringing best of all worlds • C# is statically typed
![Page 12: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/12.jpg)
It is a good sign
40 years ago 1972
40 years after2012
32 keywords changed the world for ever
60 keywords changed the world for ever
yet again
C programming language changed our notion about
programming
LINQ Changed how we interact with data
![Page 13: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/13.jpg)
How it works?
![Page 14: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/14.jpg)
Open for extension, Closed for modification.
• LINQ to Objects is a collection of extension methods declared on IEnumerable<T>
• So all collections get to use these extension methods
• These extension methods are called LINQ Standard Query Operators (LSQO in short)
• You can define your own LSQO
![Page 15: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/15.jpg)
All LINQ Standard Query Operators
All LSQOs
![Page 16: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/16.jpg)
What’s LINQ?
• Language Integrated Query• Uses Method chaining• Built by Extension Methods • Deeply integrated in the .NET framework
![Page 17: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/17.jpg)
Little Jargons
• Extension Method– A static method of a static class that let you
extend the behavior of the class. • Lambda Expression
– An inline/concise (if you will) representation of a function
• Functor– A place holder for functions
![Page 18: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/18.jpg)
Extension methods
Extension methods show up with a little down blue arrow. This distinguishes them from native methods
![Page 19: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/19.jpg)
How to declare a lambda expression?
Grammar • (variables involved separated by comma ) => (expression involving the variables)
[Example] (customer => customer.City == “London”)
This is also an unary predicate
![Page 20: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/20.jpg)
Declaring a functor
• Use Func<…> • There are several overloads. • Func<int,bool> matches any function that takes
an int and returns a bool• Func<string,string,int> matches any function that
takes two strings as input and returns an integer. • There are 17 overloaded version. That’s a lot. • The last one is the return type
![Page 21: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/21.jpg)
LINQPad – Your C# Snippet Editor
It is beyond LINQ• C# Snippet compiler• F# Snippet compiler• Test External APIs
http://www.linqpad.net/
Most of today’s demo are shown in LINQPad
![Page 22: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/22.jpg)
LINQ Operators (that we shall cover)
• Restriction Operators• Projection Operators• Partitioning Operators• Set Operators• Sorting Operators• Element Operators• Casting Operators• Quantification Operators
![Page 23: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/23.jpg)
Restriction Operators
Where Distinct
![Page 24: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/24.jpg)
Where
• Create a query running which will return those where the given condition is true.
//Return all customers who are from “London” Customers.Where ( c => c.City == “London”)
![Page 25: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/25.jpg)
Distinct
• Create a query running which will remove duplicate elements from the source collection; if present.
//Return all unique customer cities cutomerCities.Distinct();
![Page 26: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/26.jpg)
Projection/ConversionTable # 1
Sam | Smith | 25Lori | Smith | 23
View #1
Sam SmithLori Smith
View #2
Sam 25Lori 23
Select
SelectMany
ToList
ToArray
ToLookupToDictionar
y
![Page 27: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/27.jpg)
Select• Create a query running which will project the
elements of the collection is a way mentioned in the lambda expression provided.
Customers.Select( c => c.City) //Project customer city
Customer City
Sam London
Danny Paris
City
London
Paris
![Page 28: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/28.jpg)
SelectMany• Create a query, that when executed projects
all value elements in an associative container, a dictionary for example
//Returns all states for all countries• countryStates.SelectMany ( c => c.Value)
![Page 29: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/29.jpg)
ToList
• Create a query that when executed projects the result of the query to a strongly typed list.
//Projects orders to a strongly typed list Orders.Where(order => order.Amount > 200).ToList();
![Page 30: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/30.jpg)
ToArray
• Create a query that when executed projects the result of the query to a strongly typed array.
//Projects the result of the query to an array Orders.Where(order => order.Amount >
200).ToArray();
![Page 31: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/31.jpg)
ToDictionary
• Projects the result of a query to a dictionary. User have to define the key using the lambda expression.
//Segregating a list of names in two lists, boy name
//lists and girl name lists. nameList1.ToDictionary (c => c,c=>boys.Contains(c)?"boy":"girl");
![Page 32: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/32.jpg)
ToLookup
• Create a query that when executed creates a lookup table.
//Creating a lookup of unique domain names• string emails =
"[email protected],[email protected],[email protected],[email protected]"; emails.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
.Select(c => c) .ToLookup(c => c.Substring(c.IndexOf('@') +
1).Trim())•
![Page 33: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/33.jpg)
Partitioning Opeartors
Take TakeWhile
Skip SkipWhile
![Page 34: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/34.jpg)
Take
• Create a query that when executed returns only the first N entries mentioned as parameter.
//Take first 10 orders
Orders.Take(10);
![Page 35: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/35.jpg)
TakeWhile
• Create a query that when executed returns the first N elements from the source collection as long as the condition passed as lambda expression is met.
//Take orders from start as long as order amount is
//less than 100. Orders.TakeWhile(c => c.Amount < 100);
![Page 36: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/36.jpg)
Skip
• Create a query that when run, skips the first N elements and return the rest.
//Returns all orders saving the first one. Orders.Skip(1);
![Page 37: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/37.jpg)
SkipWhile
• Create a query that when run, skips the first few elements from the source collection as long as the condition, passed as lambda expression is met.
//Skip orders if the are delivered Orders.SkipWhile(ord => ord.Delivered);
![Page 38: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/38.jpg)
Set Operators
Union
Intersect
Except
![Page 39: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/39.jpg)
Intersect
• Creates a query, that when run returns values from the intersect of two given sets.
//Find intersection of two collection listA.Intersect(setB);
• Not in-place unlike IntersectWith()
![Page 40: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/40.jpg)
Union
• Creates a query that when run returns the union of two given sets
//Returns union of two collections listA.Union(setB);
![Page 41: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/41.jpg)
Except
• Creates a query that when run returns the elements present in the calling set object but not in the argument set.
//Returns elements that are in listA //but not in listB• listA.Except(setB);
![Page 42: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/42.jpg)
Sorting Operators
OrderBy
ThenBy
OrderByDescending
ThenByDescending
![Page 43: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/43.jpg)
OrderBy
• Use to sort a collection by some field of the elements. Say sort a collection of Employees by their age.
//sort all employees by their age employees.OrderBy(employee => employee.Age);
![Page 44: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/44.jpg)
OrderByDescending
• Same as OrderBy, just that the order will be descending.
//sorts all employees in descending order of age employees.OrderByDescending(employee =>
employee.Age);
![Page 45: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/45.jpg)
ThenBy
• Once you have sorted the source collection using OrderBy, you can use ThenBy to sort it again by another field. Cascaded OrderBy() calls is redundant. Only the last call applies.
Employees.OrderBy(employee => employee.Age)//order by age.ThenBy(employee => employee.Salary)//then by
salary;
![Page 46: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/46.jpg)
ThenByDescending
• Same as ThenBy, just that it sorts in descending order.
Employees.OrderBy(employee => employee.Age)//order by age.ThenByDescending(employee => employee.Salary)//then by descending
salary;
![Page 47: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/47.jpg)
Element Operators
First
Last
ElementAtElementAtOrDefaul
t
DefaultIfEmpty
Count LongCount
FirstOrDefault
LastOrDefault
![Page 48: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/48.jpg)
First
• Return the first element or the first element matching the condition passed as lambda expression or the first one if nothing is passed.
//Returns the first order in the listOrder firstOrder = Orders.First(); //Returns the first order coming from BangaloreOrder = Orders.First(order => order.City ==
“Bangalore”);
![Page 49: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/49.jpg)
Last
• Return the last element from the source collection or the last element matching the given condition passed as lambda expression
//Returns the last orderOrder = Orders.Last(); //Returns the last order coming from BangaloreOrder = Orders.Last(order => order.City ==
“Bangalore”);
![Page 50: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/50.jpg)
Count
• Returns the count of elements in the source collection
//Returns the count of orders int totalOrders = Orders.Count(); //Returns the count of orders from Paris int totalOrders = Orders.Count(o => o.City ==
“Paris”);
![Page 51: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/51.jpg)
LongCount
• Returns the count of the source collection. However this one wraps the result as a long rather than an integer. So the range of value is higher. Advised to avoid unless really needed.
long totalOrders = Orders.LongCount();//avoid using
![Page 52: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/52.jpg)
ElementAt• Returns the element at a given index. Advised
not to use on collections that natively don’t support indexing like IDictionary Implementations.
//indexing starts at 0. So 10th element is at 9th Order tenthOrder = Orders.ElementAt(9);
![Page 53: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/53.jpg)
ElementAtOrDefault
• If there is no element found at the given index, this operator returns the default value for the data type of the given collection. For example for an integer collection it would return 0. For classes it returns null.
//If there is no 10th element set the default value. Order tenthOrder = Orders.ElementAtOrDefault(9);
![Page 54: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/54.jpg)
Casting Operators
Cast OfType
AsEnumerable
![Page 55: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/55.jpg)
AsEnumerable• Wraps all the elements in a strongly typed
source collection of type in an IEnumerable<T>. This is used to continue the pipe line.
//strongly typed List<Order> orders = GetOrders(Yesterday); //loosely typed IEnumerable<Order> iOrders = orders.AsEnumerable(); //strongly typed again orders = iOrders.ToList();
•
![Page 56: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/56.jpg)
Cast• Cast all elements in the source collection to
the given type; if possible.
List<Match> matches = //returning a MatchCollection with all matches Regex.IsMatch(“ACGTACAGGACGA”, “CG”) //casting it to a IEnumerable<Match> instance .Cast<Match>()
//Projecting the result to a list .ToList();
![Page 57: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/57.jpg)
OfType• Extracts elements from the source collection
that are of the given type.
//Extract only the employees from a list of employees
IEnumerable<Developer> devs = allEmployees.OfType<Developer>();
![Page 58: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/58.jpg)
Create values
Repeat
Range
Empty
![Page 59: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/59.jpg)
Empty
• Creates an empty sequence
//Creates an empty sequenceEnumerable.Empty();
![Page 60: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/60.jpg)
Range
• Creates a range of values from given range
//Creates a range from 1 to 100 Enumerable.Range(1,100);
![Page 61: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/61.jpg)
Repeat
• Create N copies of the given object.
//Creates a list of strings with the same string //repeated. List<string> voices = Enumerable .Repeat(“World is not enough”,10) //projecting the list to a strongly typed
list. .ToList();
![Page 62: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/62.jpg)
Quantification Operators
Any
Single
SingleOrDefault
![Page 63: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/63.jpg)
Any
• Create a query running which will return true if there is at least one element satisfying the given condition.
//Checks if there is any customer form “London” or not
Customers.Any ( c => c.City == “London”)
![Page 64: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/64.jpg)
Single
• Create a query running which will return the single element matching the condition. If no such element is found, it throws exception
//Finds the only customer from NYC Customers.Single( c => c.City == “NYC”)
![Page 65: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/65.jpg)
SingleOrDefault
• Create a query running which will return the single element matching the condition. If no such element is found, it returns the default value.
//Finds the only customer from London //if no such element is found, it returns default //in this case it is null. Customers.SingleOrDefault ( c => c.City ==
“London”)
![Page 66: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/66.jpg)
Pull the zipper
Zip
Mr.
Mrs.
Master.
Ms.
Sam
Jen
Ben
Jace
Smith
Mr. Sam Smith
![Page 67: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/67.jpg)
Zip• Puts together two entities from two different
lists at the same index and creates a collection of the concatenated results.
//Creates full name with salutation for Smith familystring[] salutations =
{"Mr.","Mrs.","Master.","Ms."};string[] firstNames = {"Sam","Jen","Ben","Jace"};string lastName = "Smith";Salutations .Zip(firstNames, (sal , first) => sal + " " +
first) .ToList() .ForEach(name => Console.WriteLine(name +
lastName));
![Page 68: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/68.jpg)
Some example LINQ ScriptsExciting but not really from our domain
![Page 69: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/69.jpg)
Spam E-mail domain Indexing
Output
b.com:3d.com:1
![Page 70: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/70.jpg)
Finding all Winning Paths in Tic-Tac-Toe
• For an arbitrary board size n, for 3x3 , n = 3
![Page 71: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/71.jpg)
Finding all Horizontal Paths
Expanding LINQ Query over multiple lines enable
Debugging
![Page 72: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/72.jpg)
LINQ to Flat file Provider
See how Func<> is being used
![Page 73: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/73.jpg)
Using LINQ with .NET Reflection
• This query will list all LSQOs
![Page 74: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/74.jpg)
Password Generator
![Page 75: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/75.jpg)
Fuzzy string match
![Page 76: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/76.jpg)
Loop to LINQ
1. Get the condition out2. Make a lambda out of it3. Find the nature of your loop4. Use the appropriate operator
How can I do it ? Get it done? Use Re-sharper
![Page 77: Think in linq](https://reader035.vdocument.in/reader035/viewer/2022062412/58cef5c71a28abab738b4eb3/html5/thumbnails/77.jpg)
Loop => LINQ example
List<int> evenNumbers = new List<int>();
for(int k = 0; k < 100 ; k ++) if (k % 2 == 0) evenNumbers.Add(k);
evenNumbers.AddRange ( Enumerable.Range(0,100) .Where( k => k % 2 == 0) );
Loop
LINQ
This loop is a filter loop