Download - Coding with LINQ, Patterns & Practices

Transcript
Page 1: Coding with LINQ, Patterns & Practices

Coding with LINQ, Patterns & Practices

LINQ & Functional ways

© Tuomas Hietanen (LGPLv3)

Page 2: Coding with LINQ, Patterns & Practices

LINQ (Monads)

• Two types of functions

– Queries and Aggreagtes

QUERY: - returns another container of the same type

AGGREGATE: - returns result

(Wrapper) Wrapped type, In this case IEnumerable<T>

© Tuomas Hietanen

Page 3: Coding with LINQ, Patterns & Practices

LINQ SELECT = LIST.MAP (Query)

MAP function:

IEnumerable< > IEnumerable< >

© Tuomas Hietanen

Page 4: Coding with LINQ, Patterns & Practices

LINQ WHERE= LIST.FILTER (Query)

FILTER function:

IEnumerable< > IEnumerable< >

© Tuomas Hietanen

Page 5: Coding with LINQ, Patterns & Practices

LINQ AGGREGATE= LIST.FOLD (Aggregate)

FOLD function:

IEnumerable< >

© Tuomas Hietanen

Page 6: Coding with LINQ, Patterns & Practices

Other Aggregates (to make things easier)

Function Aggregate function

LIST.SUM Add every to

LIST.COUNT Add (+1) to

LIST.MAX Select bigger of or

...

© Tuomas Hietanen

Page 7: Coding with LINQ, Patterns & Practices

LINQ SELECTMANY - Not pure, has many overrides

SELECT function:

IEnumerable< >

© Tuomas Hietanen

Page 8: Coding with LINQ, Patterns & Practices

LINQ SELECTMANY - Not pure, has many overrides

SELECT function:

© Tuomas Hietanen

Page 9: Coding with LINQ, Patterns & Practices

Old Legacy Way New C#, LINQ F#

var result = new List<T>(); foreach(var x in xs){ result.Add(...); ... }

var result = from x in xs select … //same as var result = xs.Select(x=>...);

let result = List.map (fun x -> ...) xs

foreach(var x in xs){ if(x=...){...} }

var result = from x in xs where … //same as var result = xs.Where(x=>...);

let result = List.filter(fun x -> ...) xs

var result = new T(); foreach(var x in xs){ result = ...; ... }

//many ways, based on var result = xs.Aggregate(…);

//many ways, based on let result = List.fold (fun f -> ...) xs //also supports unfold

foreach(var x in xs){ foreach(var y in ...){ .... } }

var result = from x in xs from y in … select … //same as var result = xs.SelectMany(...);

//SelectMany is not pure, so depends on situation. E.g. List.collect, or seq {...} let result = List.collect (fun x -> ...) xs © Tuomas Hietanen

Page 10: Coding with LINQ, Patterns & Practices

Do use lists!

• Don’t return Null. Prefer throw InvalidOperationException on error and Enumerable.Empty<T>() on case of empty list

• Don’t modify collections, do use new ones list.RemoveAt(0)

newlist = list.Where(interestingItems => ...)

• Use IEnumerable<T> not List<T> or IList<T> – It is the baseclass and default for LINQ

– You can always say .toList() to evaluate the lazy collection.

© Tuomas Hietanen

Page 11: Coding with LINQ, Patterns & Practices

Safe class design, avoid side effects

• Don’t reuse variables x = x + 1 y = x + 1

• Avoid global and class variables. Use method parameters – Better for function composition

• Don’t overcapuslate layers or class structures – No coding for fun: Focus on the functionality

• Declarative programming. – ”yield return” is ok in some cases, but not really

declarative.

• Also old design practices do still apply (=> FxCop).

© Tuomas Hietanen

Page 12: Coding with LINQ, Patterns & Practices

F# list vs seq

• List is F# default

– Linked list

– Good for recursive methods

• Seq is IEnumerable<T>

– Lazy evaluation

– Good for .NET interop

© Tuomas Hietanen