Your SlideShare is downloading. ×
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Mixing Functional and Object Oriented Approaches to Programming in C#

1,361

Published on

Mixing Functional and Object Oriented Approaches to Programming in C#, Michael Wagg, Mark Needham

Mixing Functional and Object Oriented Approaches to Programming in C#, Michael Wagg, Mark Needham

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
1,361
On Slideshare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
0
Comments
0
Likes
0
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide
  • Lazy evaluation
  • Go faster!!!
  • origins of functional programming are found in lambda calculation/maths
  • functions that take in a function or return a function. Need to have first class functions in the language to do that. We have that with all the LINQ methods - select, where, and so on.
  • the whole premise of functional programming with side effect free functions assumes that we have immutable data. We can't achieve this idiomatically in C# because the language isn't really designed for it. I want to put an example of how immutability is easy in F#, can that go in this section?
  • iterators in C# do this with yield keyword It's not necessary to have lazy evaluation to be functional but it's a characteristic of some functional languages.
  • seems quite obvious but the most extreme guideline to follow is that we shouldn't need to store anything in variables. Look at the data as a whole if we don't store any intermediate values then we truly do have some data that we are passing through different filters and applying some transformation
  • it's quite like the pipes and filters architectural pattern in fact. This is the way that we can combine functions on the unix command line.
  • what is CPS?   is where we pass in a function that represents the rest of the program which will be called with the result of another function.
  • what is CPS?   is where we pass in a function that represents the rest of the program which will be called with the result of another function.
  • what is CPS?   is where we pass in a function that represents the rest of the program which will be called with the result of another function.
  • the idea is that the rest of the program is contained in the continuation so we don't need to come back to the call site.
  • the idea is that the rest of the program is contained in the continuation so we don't need to come back to the call site.
  • the idea is that the rest of the program is contained in the continuation so we don't need to come back to the call site.
  • Encapsulates the state but over complicates the program flow perhaps
  • Encapsulates the state but over complicates the program flow perhaps
  • Transcript

    • 1. Mixing Functional and Object Oriented approaches to programming in C# Mike Wagg & Mark Needham
    • 2. C# 1.0
    • 3. http://www.impawards.com/2003/posters/back_in_the_day.jpg
    • 4. int[] ints = new int[] {1, 2, 3, 4, 5}  
    • 5. int[] Filter(int[] ints) {     ArrayList results = new ArrayList();     foreach (int i in ints)     { if (i % 2 == 0) { results.Add(i); }     }     return results.ToArray(typeof(int)); }
    • 6. int[] ints = new int[] {1, 2, 3, 4, 5}  
    • 7. int[] Filter(int[] ints) {     ArrayList results = new ArrayList();     foreach (int i in ints)     { if (i >3) { results.Add(i); }     }     return results.ToArray(typeof(int)); }
    • 8. int[] Filter(int[] ints) {     ArrayList results = new ArrayList();     foreach (int i in ints)     { if ( i % 2 == 0 ) { results.Add(i); }     }     return results.ToArray(typeof(int)); }
    • 9. int[] Filter(int[] ints) {     ArrayList results = new ArrayList();     foreach (int i in ints)     { if ( i > 3 ) { results.Add(i); }     }     return results.ToArray(typeof(int)); }
    • 10. interface IIntegerPredicate { bool Matches(int value); }
    • 11. class EvenPredicate : IIntegerPredicate { bool Matches(int value) { return value % 2 == 0; } }
    • 12. class GreaterThanThreePredicate : IIntegerPredicate { bool Matches(int value) { return value > 3; } }
    • 13. int[] Filter(int[] ints, IIntegerPredicate predicate) {     ArrayList results = new ArrayList();     foreach (int i in ints)     { if (predicate.Matches(i)) { results.Add(i); }     }     return results.ToArray(typeof(int)); }
    • 14. int[] ints = new int[] {1, 2, 3, 4, 5 }; int[] even = Filter(ints, new EvenPredicate()); int[] greaterThanThree = Filter(ints, new GreaterThanThreePredicate());
    • 15. interface IIntegerPredicate { bool Matches(int value); }
    • 16. bool delegate IntegerPredicate(int value);
    • 17. bool Even(int value) { return value % 2 == 0; }
    • 18. bool GreaterThanThree(int value) { return value > 3; }
    • 19. int[] Filter(int[] ints, IntegerPredicate predicate) {     ArrayList results = new ArrayList();     foreach (int i in ints)     {                 if (predicate(i)) { results.Add(i); }     }     return results.ToArray(typeof(int)); }
    • 20. int[] ints = new int[] {1, 2, 3, 4, 5 }; int[] even = Filter(ints,  new IntegerPredicate(Even)); Int[] greaterThanThree = Filter(ints,  new IntegerPredicate(GreaterThanThree));
    • 21. C# 2.0  
    • 22. Inference int[] ints = new int[] {1, 2, 3, 4, 5 }; int[] even = Filter(ints,  new IntegerPredicate(Even)); Int[] greaterThanThree = Filter(ints,  new IntegerPredicate(GreaterThanThree));
    • 23. Inference int[] ints = new int[] {1, 2, 3, 4, 5 }; int[] even = Filter(ints, Even); Int[] greaterThanThree = Filter(ints, GreaterThanThree); The compiler can infer what the type of the delegate is so we don’t have to write it.
    • 24. Generics delegate bool IntegerPredicate(int value);
    • 25. Generics delegate bool Predicate<T> (T value);
    • 26. Generics int[] Filter(int[] ints, IntegerPredicate predicate) { ArrayList results = new ArrayList(); foreach (int i in ints) { if (predicate(i)) { results.Add(i); } } return results.ToArray(typeof(int)); }
    • 27. Generics T[] Filter<T>(T[] values, Predicate<T> predicate) { List<T> results = new List<T>(); foreach (T i in value) { if (predicate(i)) { results.Add(i); } } return results.ToArray(); }
    • 28. Generics IEnumerable<T> Filter<T>(IEnumerable<T> values, Predicate<T> predicate) { List<T> results = new List<T>(); foreach (T i in value) { if (predicate(i)) { results.Add(i); } } return results; }
    • 29. Iterators IEnumerable<T> Filter<T>(IEnumerable<T> values, Predicate<T> predicate) { List<T> results = new List<T>(); foreach (T i in value) { if (predicate(i)) { results.Add(i); } } return results; }
    • 30. Iterators IEnumerable<T> Filter<T>(IEnumerable<T> values, Predicate<T> predicate) { foreach (T i in value) { if (predicate(i)) { yield return i; } } }
    • 31. Anonymous Methods IEnumerable<int> greaterThanThree = Filter(ints, GreaterThanThree);
    • 32. Anonymous Methods IEnumerable<int> greaterThanThree = Filter(ints, delegate(int value) { return value > 3; });
    • 33. Anonymous Methods int minimumValue = 3; IEnumerable<int> greaterThanThree = Filter(ints, delegate(int value) { return value > minimumValue; }); Anonymous methods add support for closures. The delegate captures the scope it was defined in.
    • 34. C# 3.0  
    • 35. Lambdas int minimumValue = 3; IEnumerable<int> greaterThanThree = Filter(ints, delegate(int value) { return value > minimumValue; });
    • 36. Lambdas int minimumValue = 3; IEnumerable<int> greaterThanThree = Filter(ints, value => value > minimumValue);
    • 37. More Type Inference int minimumValue = 3; IEnumerable<int> greaterThanThree = Filter(ints, value => value > minimumValue);
    • 38. More Type Inference int minimumValue = 3; var greaterThanThree = Filter(ints, value => value > minimumValue);
    • 39. Extension Methods int minimumValue = 3; var greaterThanThree = Filter(ints, value => value > minimumValue);
    • 40. Extension Methods int minimumValue = 3; var greaterThanThree = ints.Filter(value => value > minimumValue);
    • 41. Anonymous Types var anonymous = new { Foo = 1, Bar = “Bar” }
    • 42. LINQ
    • 43. LINQ New delegates in System namespace Action<T>, Action<T1, T2>, Func<TResult>, Func<T1, TResult> etc.
    • 44. LINQ New delegates in System namespace Action<T>, Action<T1, T2>, Func<TResult>, Func<T1, TResult> etc. System.Linq Extension methods Where, Select, OrderBy etc.
    • 45. LINQ New delegates in System namespace Action<T>, Action<T1, T2>, Func<TResult>, Func<T1, TResult> etc. System.Linq Extension methods Where, Select, OrderBy etc.   Some compiler magic to translate sql style code to method calls
    • 46. LINQ var even = ints.Where(value => value % 2 == 0)   var greaterThanThree = ints.Where(value => value > minimumValue)   or var even = from value in ints                   where value % 2 == 0                   select value   var greaterThanThree = from value in ints                                         where value > minimumValue                                                   select value                                       
    • 47. A (little) bit of theory
    • 48. http://www.flickr.com/photos/stuartpilbrow/2938100285/sizes/l/
    • 49. Higher order functions
    • 50. Immutability
    • 51. Lazy evaluation
    • 52. Recursion & Pattern Matching
    • 53. Transformational Mindset We can just pass functions around instead in most cases - find an example where it still makes sense to use the GOF approach though.
    • 54. Input -> ??? -> ??? -> ??? ->  Output
    • 55. http://www.emt-india.net/process/petrochemical/img/pp4.jpg
    • 56. So why should you care?
    • 57. Functional can fill in the gaps in OO code  
    • 58. Abstractions over common operations means less code and less chances to make mistakes
    • 59. So what do we get out of the box?
    • 60. Projection
    • 61.  
      •  
      •  
      •   people.Select(person => person.Name)
      •  
      •  
    • 62.  
      •  
      •  
      • people.SelectMany(person => person.Pets)
    • 63. Restriction  
    • 64.  
      •         
      •  
      • people.Where(person => person.HasPets)
      •  
    • 65. Partitioning  
    • 66.  
      •  
      •  
      • people.Take(5)
    • 67.  
      •  
      •  
      • people.Skip(5)
    • 68.  
      •  
      •  
      •              people.TakeWhile(person => 
      •                              person.Name != &quot;David&quot;)
    • 69.  
      •  
      •  
      •              people.SkipWhile(person => 
      •                                  person.Name != &quot;David&quot;)
    • 70. Set  
    • 71.  
      • people.Select(person => person.Name)
      • .Distinct()
    • 72.  
      •   people.Union(someOtherPeople)
      •  
    • 73.  
      •  
      •  
      • people.Intersect(someOtherPeople)
    • 74.  
      •  
      •  
      • people.Except(someOtherPeople)
    • 75. Ordering and Grouping  
    • 76.  
      •  
      •  
      • people.OrderBy(person => person.Name)
      •  
      •  
    • 77.  
      •  
      •  
      • people.GroupBy(person => person.Name)
    • 78. Aggregation  
    • 79.  
      •  
      •  
      • people.Count()
    • 80.  
      •  
      •  
      • people.Select(person => person.Age)
      • .Sum()
    • 81.  
      •  
      •  
      • people.Select(person => person.Age)
      • .Min()
    • 82.  
      •  
      •  
      • people.Select(person => person.Age)
      • .Max()
    • 83.  
      •  
      •  
      • people.Select(person => person.Age)
      • .Average()
    • 84.  
      • Things can get more complex
    • 85.  
      •  
      •  
      •        people.Select(person => person.Age)
      •              .Aggregate(0, (totalAge, nextAge) => 
      •                      nextAge % 2 == 0 
      •                          ? nextAge + totalAge 
      •                          : totalAge)
    • 86.  
      •  
      •  
      •         people.Join(addresses,          
      •                 person => person.PersonId,  
      •                  address => address.PersonId,     
      •                 (person, address) => new { 
      •                                          person, address})
    • 87. We can just pass functions around instead in most cases - find an example where it still makes sense to use the GOF approach though.
    • 88.  
    • 89.  
      •  
      public class SomeObject { private readonly IStrategy strategy; public SomeObject(IStrategy strategy) { this.strategy = strategy; } public void DoSomething(string value) { strategy.DoSomething(value); } }
    • 90.  
      •  
      public class Strategy : IStrategy { public void DoSomething(string value) { // do something with string } }
    • 91.  
      •  
      public class SomeObject { private readonly Action<string> strategy; public SomeObject(Action<string> strategy) { this.strategy = strategy; } public void DoSomething(string value) { strategy(value); } }
    • 92.  
      • Hole in the middle pattern
    • 93.  
      •  
      public class ServiceCache<Service> { protected Res FromCacheOrService            <Req, Res>(Func<Res> serviceCall, Req request) {      var cachedRes = cache.RetrieveIfExists( typeof(Service), typeof(Res), request);   if(cachedRes == null)   { cachedRes = serviceCall(); cache.Add(typeof(Service), request, cachedRes); }      return (Res) cachedRes; } }
    • 94.  
      •  
      public class CachedService : ServiceCache<IService> { public MyResult GetMyResult(MyRequest request) {           return FromCacheOrService(()                   => service.GetMyResult(request), request); } }
    • 95.  
      • Passing functions around
    • 96.
      •  
      private void AddErrorIf<T>(Expression<Func<T>> fn, ModelStateDictionary modelState, Func<ModelStateDictionary, Func<T,string, string, bool>> checkFn) { var fieldName = ((MemberExpression)fn.Body).Member.Name; var value = fn.Compile().Invoke(); var validationMessage = validationMessages[fieldName]); checkFn.Invoke(modelState)(value, fieldName, validationMessage); } AddErrorIf(() => person.HasPets, modelState, m => (value, field, error) => m.AddErrorIfNotEqualTo(value,true, field, error)); AddErrorIf(() => person.HasChildren, modelState, m => (value, field, error) => m.AddErrorIfNull(value, field, error));
    • 97.  
      • Continuation Passing Style
    • 98.
      •  
      static void Identity<T>(T value, Action<T> k) { k(value); }
    • 99.
      •  
      Identity(&quot;foo&quot;, s => Console.WriteLine(s));
    • 100.
      •  
      Identity(&quot;foo&quot;, s => Console.WriteLine(s)); as compared to var foo = Identity(“foo”); Console.WriteLine(foo);
    • 101.
      •  
      public ActionResult Submit(string id, FormCollection form) {    var shoppingBasket = CreateShoppingBasketFrom(id, form);      return IsValid(shoppingBasket, ModelState,          () => RedirectToAction(&quot;index&quot;, &quot;ShoppingBasket&quot;, new { shoppingBasket.Id} ),   () => LoginUser(shoppingBasket,                  () =>                  {                    ModelState.AddModelError(&quot;Password&quot;, &quot;User name/email address was incorrect - please re-enter&quot;);                      return RedirectToAction(&quot;index&quot;, &quot;&quot;ShoppingBasket&quot;, new { Id = new Guid(id) });                 }, user =>                  {                    shoppingBasket.User = user;                      UpdateShoppingBasket(shoppingBasket);                      return RedirectToAction(&quot;index&quot;, &quot;Purchase&quot;,    new { Id = shoppingBasket.Id }); }         )); }
    • 102.
      •  
      private RedirectToRouteResult IsValid(ShoppingBasket shoppingBasket,                                       ModelStateDictionary modelState,                                        Func<RedirectToRouteResult> failureFn,                      Func<RedirectToRouteResult> successFn) {   return validator.IsValid(shoppingBasket, modelState) ? successFn() : failureFn(); }   private RedirectToRouteResult LoginUser(ShoppingBasket shoppingBasket,                                                                  Func<RedirectToRouteResult> failureFn,                                                                Func<User,RedirectToRouteResult> successFn) { User user = null; try { user = userService.CreateAccountOrLogIn(shoppingBasket); }   catch (NoAccountException) { return failureFn(); }   return successFn(user); }
    • 103.
      •  
      http://www.thegeekshowpodcast.com/home/mastashake/thegeekshowpodcast.com/wp-content/uploads/2009/07/wtf-cat.jpg
    • 104. So what could possibly go wrong?   http://icanhascheezburger.files.wordpress.com/2009/06/funny-pictures-cat-does-not-think-plan-will-fail.jpg
    • 105. Hard to diagnose errors  
    • 106. var people = new [] { new Person { Id=1, Address = new Address { Road = &quot;Ewloe Road&quot; }}, new Person { Id=2}, new Person { Id=3, Address = new Address { Road = &quot;London Road&quot;}} }; people.Select(p => p.Address.Road); 
    • 107. Null Reference Exception on line 23
    • 108. http://www.flickr.com/photos/29599641@N04/3147972713/
    • 109. public T Tap(T t, Action action)  {     action();     return t; }
    • 110. people     .Select(p => Tap(p, logger.debug(p.Id))     .Select(p => p.Address.Road); 
    • 111. Readability  
    • 112. Lazy evaluation can have unexpected consequences  
    • 113.  
      •         IEnumerable<string> ReadNamesFromFile()         {             using(var fileStream = new FileStream(&quot;names.txt&quot;,
      •                                                          FileMode.Open))             using(var reader = new StreamReader(fileStream))             {                 var nextLine = reader.ReadLine();                 while(nextLine != null)                 {                     yield return nextLine;                     nextLine = reader.ReadLine();                 }             }         }
    • 114.  
      •         IEnumerable<Person> GetPeople()         {             return ReadNamesFromFile()
      •                      .Select(name => new Person(name));         }
    • 115.  
      •       IEnumerable<Person> people = GetPeople();           foreach (var person in people)      {          Console.WriteLine(person.Name);      }      
      •      Console.WriteLine(&quot;Total number of people: &quot; +
      •                                      people.Count());
    • 116. Encapsulation is still important  
    • 117.  
      • Total salary for a company
      •  
      • company.Employees.Select(employee =>
      •                                              employee.Salary) 
      •                                  .Sum()
      • This could lead to duplication
      • What if we add rules to the calculation?
      • Who should really have this responsibility?
      • .Sum()
    • 118. Linq isn't the problem here, it's where we have put it  
    • 119. Company naturally has the responsibility so encapsulate the logic here
    • 120.
      • class Company
      • {
      •     public int TotalSalary
      •     {
      •         get 
      •         {
      •             return employees.Select(e =>
      •                                      e.Salary).Sum();
      •         }
      •     }
      • }
    • 121. Sometimes we need to go further  
    • 122. If both Company and Division have employees do we duplicate the logic for total salary?
    • 123. IEnumerable<T> and List<T> make collections easy but sometimes it is still better to create a class to represent a collection
    • 124.  
      • class EmployeeCollection
      • {
      •     private List<Employee> employees;
      •  
      •      public int TotalSalary
      •     {
      •         get
      •          {
      •             return employees.Select(e => e.Salary).Sum();
      •          }
      •     }
      • }
    • 125. In conclusion…  
    • 126.  
    • 127. Mike Wagg mikewagg.blogspot.com [email_address] Mark Needham markhneedham.com [email_address]

    ×