linq and lambda

18
LINQ John Walsh Sample of ITT Software Development course notes Delegates Lambda expressions Generic methods Func and Action delegates Extension functions LINQ

Upload: john-walsh

Post on 26-Aug-2014

329 views

Category:

Education


3 download

DESCRIPTION

LINQ Sequences & Elements IEnumerable Lambda Expressions Chaining Lambda expressions Comprehension Queries

TRANSCRIPT

Page 1: Linq and lambda

LINQ

John Walsh

Sample of ITT Software Development course notes

• Delegates• Lambda expressions• Generic methods• Func and Action delegates• Extension functions• LINQ

Page 2: Linq and lambda

2

LINQ LINQ – The Quick Explanation

Sequences & Elements IEnumerable Lambda Expressions Chaining Lambda expressions Comprehension Queries

LINQ – The Long Explanation Delegates Lambda expressions Generic methods Func and Action delegates Extension functions LINQ

Page 3: Linq and lambda

3

LINQ – The Quick Explanation

LINQ = Language Integrated Query.

Allows you to write queries over

1. local collections e.g. Lists, Arrays that implement IEnumerable (we’ll talk about this in next slide)

2. data sources e.g. SQL database using objects that implement Iquerable

By queries we mean the ability to select and/or filter information from a collection or data source

- e.g. select all males from a list of people or from a table containing people

Sequences & Elements

LINQ works on sequences and elements Sequences : lists, array etc.. any object that implements IEnumerable (or Iqueryable for data

sources)

Element : each item in that sequence

E.g string[] names = {‘Tom’ , ‘Dick’, Harry’ }; names = sequence : Tom,Dick,Harry = elements

Page 4: Linq and lambda

4

LINQ – The Quick Explanation IEnumerable

LINQ works on collections that implement IEnumerable (and data sources that implement IQueryable)

1. IEnumerable provides methods to loop over a collection

when you use foreach (string name in names) you are indirectly using IEnumerable to iterate over collection.

2. IEnumerable extension methods are provided for querying

Query functions include: Select, where, orderby

NB: A query takes, as an input, a collection(sequence), and returns a transformed output collection (collection in, collection out)

string[] names = {"Tom" , "Dick", "Harry" };

IEnumerable< string> filterednames = names.Where(n=>n.Length > 3)

//result = Dick, Harry

• Where query takes the names collection and returns a new filtered collection

• n => n.Length > 3 is a lambda expression

Above Means : for each item n in names list, if n.length > 3 put it in returned sequence

Page 5: Linq and lambda

5

LINQ – The Quick ExplanationLambda Expressions

n=>n.Length > 3 is lambda expression (a short hand way of writing a function)

This functions tells the where query how to do the filtering (how to build the returned sequence)

n => n.Length > 3

A lambda expression has the following form :

input parameters => expression/statements;. (Note : expression/statement determines return type)

n => n.length > 3

- n is the input parameter. In this case each name string in list (we are iterating over string array of names)

- n.length > 3 is the statement : returns true or false , If it returns true, ‘where’ method will put n into the returned list

string[] names = {"Tom" , "Dick", "Harry" };

IEnumerable< string> filterednames = names.Where(n=>n.Length > 3)

For each item n in names list, if n.length > 3 is true put it in the returned sequence

Page 6: Linq and lambda

6

LINQ – The Quick ExplanationChaining Lambda expressions

LINQ queries can be chained one after another

This works because each query takes a sequence as an input and returns a sequence as an output

Where takes in a sequence (names) and return a sequence

This sequences is fed into OrderBy , which returns a sequence

This sequences is fed into select, which returns a sequence

Where (n => n.Contains('a'))

n is each name in list : if n contains an ‘a’ it will make it into the returned sequence

OrderBy (n => n.Length)

n is each name in list : returned list contains n ordered by length

Select (p => p.ToUpper() )

p is each name in list : returned list contains n converted to uppercase

string[] names = {"Tom" , "Dick", "Harry", "Mary" };

IEnumerable<string> filterednames = names.Where (n => n.Contains('a')) .OrderBy (n => n.Length) .Select (p => p.ToUpper());//result = MARY, HARRY

Note : input is just a place holderAny name will do .. n, p

Page 7: Linq and lambda

7

LINQ – The Quick ExplanationComprehension Queries

Comprehension Queries provide an alternative syntax to lambda queries

string[] names = {"Tom" , "Dick", "Harry", "Mary" };

IEnumerable<string> filterednames = names.Where (n => n.Contains('a')) .OrderBy (n => n.Length) .Select (p => p.ToUpper());

string[] names = {"Tom" , "Dick", "Harry", "Mary" };

IEnumerable<string> filterednames1 = from n in names where n.Contains('a') orderby n.Length select n.ToUpper();

Query using Lambda Expressions

Same Query using comprehension Queries

Note : Unlike Lambda, have to use same variable name (n here) throughout query

People who are familiar with SQL may feel more comfortable using ‘comprehension queries’

Page 8: Linq and lambda

8

LINQ – The Quick ExplanationSome More Examples

Please see sample projects (from class) for more examples of LINQ queries

Page 9: Linq and lambda

9

LINQ – The Long Explanation

In order to fully understand LINQ you need to understand

Delegates

Lambda expressions

Generic methods

Func and Action delegates

Extension functions

LINQ

Page 10: Linq and lambda

10

Delegates

Up till now you have only passed types into and out of method Void methodname ( int p1, string p2)

However you can also pass functions as parameters to functions (WTF!!!) Void methodname ( int p1, function p2) not exactly right.. Actually pass delegate which is a reference to function

Delegates are used to pass functions around just like you pass variables around.Void methodname(int p1, DelegateName p2){ int x = p2(); } DelegateName will hold a reference to a function!

Inside methodname(), You can call p2 like you normally call a function : int x = P2();

In essence delegates allow you to treat functions just like you would treat a variable Assigning it to another variable

Passing it as a parameter

Page 11: Linq and lambda

11

Delegates

//1. Declare delegate (will be used to hold ref to functions) looks just like function method, prepended with type Delegate delegate int calcMethod (int x1, int x2);

//2. Declare 2 functions that exactly match delegate definition (delegate will hold reference to these) static int addmethod (int n1, int n2) { return n1 + n2; } static int multiplymethod (int n1, int n2) { return n1 + n2; }

//3. Declare a function that will accept delegate as parameter (in essence we can pass functions into the calculate function!! static int Calculate(int n1, int n2, calcMethod fn) { return fn(n1, n2); }

static void Main(string[] args) { int result = 0;

Console.WriteLine(“ To add the numbers (5,6) enter A, To multiply the numbers (5,6) enter M"); char choice = Console.ReadKey().KeyChar;

//Pass the add or multiply function into the calculate function if(choice == 'a' || choice == 'A') result = Calculate(5, 6, addmethod); else result = Calculate(5, 6, multiplymethod );

Console.WriteLine("Result = " + result.ToString() + "; Hit key to finish"); Console.ReadLine(); }

Page 12: Linq and lambda

12

Lambda Expression/Method

delegate int calcMethod (int x1, int x2);

static int addmethod (int n1, int n2) static int multiplymethod (int n1, int n2) { { return n1 + n2; return n1 * n2; } }

SO : In the previous slide we defined a delegate and 2 methods to match that delegate

We then wrote a method that would accept the delegate as a parameter (so that we could pass in the add or multiply function)

static int Calculate(int n1, int n2, calcMethod fn) { return fn(n1, n2); }

result = Calculate(5, 6, addmethod); or result = Calculate(5, 6, multiplymethod ); We called the method as follows:

Lambda methods allow us to define what the function is ‘inplace’

result = Calculate(5, 6, (int x, int y) => { return x + y; }); or result = Calculate(5, 6, (int x, int y) => { return x * y; });

Compiler can infer types so we can even shorten Lambda method above to result = Calculate(5, 6, (x, y) => x + y );

Can omit the ‘return’ for 1 line statement blocks (the x + y bit)

Page 13: Linq and lambda

13

Lambda Expression/Method

So Lambda Methods provide a quick way of defining a function

Anywhere where we want to pass a delegate we can use a lambda method ( reducing the amount of code we need to write)

A lambda expression has the following form :

input parameters => expression/statements;. (Note : expression/statement determines return type)

x => x * x

x is the input parameter. x * x is the statement : returns the value of x multiplied by x what is passed into the function

x => x * x Note

• ‘return’ is implied when using single statement• Types are inferred by types passed into lambda

method

int squared( int x){

return (x * x);}

==is the same as ==>

Advantage of Lambda methods- Don’t have to declare functions somewhere else in code , you can write them ‘In place’ i.e. In previous example, when using lambda methods, we dont need to seperately declare addmethod() and multiplymethod(). The lambda method describes the function and is written ‘in place’

Page 14: Linq and lambda

14

Generic methods

// Declare a generic method : It is generic because it can accept and work on ANY type // T is a placeholder. When the method it called , T will be replaced by the passed in type // You declare types before the () and use them as your input and/or output and in your method body. static void swap<T> (ref T a, ref T b) { T temp = a; a = b; b = temp; }

//Calling the Generic methodPublic Static Main(){

int a = 1, b = 2;string s1 = "string1", s2 = "string2";//Using Generic Swap method to swap ints , and then the very same swap method to swap stringsswap<int> (ref a, ref b); swap<string>(ref s1, ref s2);

}

 A generic method accepts parameters & returns values of any type.This means that instead of specifying what type (int, string etc..) each parameter is, you use a placeholder that can accept any typeThis allow you to write very ‘Generic’ methods : i.e methods that accept any type

Page 15: Linq and lambda

15

Func and Action delegates

delegate TResult Func <out TResult> (); //<- method that can return any type

delegate TResult Func <in T, out TResult> (T arg); //<- method that can take 1 input of any type & return any type

delegate TResult Func <in T1, in T2, out TResult> (T1 arg1, T2 arg2); //<- method that can take 2 input of any type & return any type

delegate TResult Func <in T1, in T2, int T3, out TResult> (T1 arg1, T2 arg2, T3 arg3); .... and so on up to T6

delegate void Action (); //<- method that returns void

delegate void Action <in T> (T arg); //<- method that can take 1 input of any type & returns void

delegate void Action <in T1, in T2> (T1 arg1, T2 arg2); //<- method that can take 2 inputs of any type & returns void

delegate void Action <in T1, in T2, in T3> (T1 arg1, T2 arg2, T3 arg3);.... and so on up to T6

Using Generics and delegates makes it possible to write a small set of extremely general methods that can be used anywhere.

These are called Func and Actions delegates (provided by .Net is System namespace)Func : set of delegate methods that take x inputs and return 1 outputAction : set of delegate methods that take x inputs and return 0 outputs (returns void)

Page 16: Linq and lambda

16

Extension methods

Public static Class StringHelper //<- static class to hold extension metods for string Type

{ public static bool IsCapitalised( this string s) //using this on first parameter indicates its an extension method of that { // parameter type i.e IsCapitalised is an extension method of the class

string return char.IsUpper(s[0]); //is first letter a capital

}}

This method can be called as follows

string s = “Dublin”;

bool isCapitalised = s.IsCapitalised( ) ; //IsCapitalised looks like its a method of string

//NB : looks like we are calling a method contained in the string class but it is actually an extension method

Extension methods allow us to ‘add’ methods to existing types/classes, without changing that Type/Class.• They are static methods contained in a static class• The ‘this modifier’ is used to ‘mark them’ as extension methods of a particular class/Type• The method can then be called as if it were a normal method contained in that class

Page 17: Linq and lambda

17

LINQ

Collection that implements Ienumerable Extension method on IEnumerable

Var filterednames = names.Where (n => n.Contains('a'))

Func delegate that accepts a type and returns a bool (Lambda expression used to define the function referenced by delegate)

Generics , Func/Action delegates, Extension methods, & Lambda Expressions make LINQ query methods (select, where ..) possible

The query methods use1. Extension methods on IEnumerable (so you can write readable code like collection. where(..) )2. Func/Action methods as parameters to query, that determines what work query should do

(what it filters, i.e what makes it into the returned list)• (e.g ‘where’ method takes Func <in T, out TResult>

• T is the type of member in collection, • TResult is a returned bool (to indicate if member is part of returned collection)

3. The Func/Action methods are passed in as Lambda Expressions (for readability)

Page 18: Linq and lambda

18References

LINQ Language

http://msdn.microsoft.com/en-us/library/vstudio/bb397897(v=vs.100).aspx

101 LINQ samples http://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b