Search

Categories

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Send mail to the author(s) E-mail

# Wednesday, 15 October 2014

Language Integrated Query
LINQ provides a general purpose query facility

MS… IEnumerable<T>

static void Main() { // Can hide anything behind IEnumerable eg a database // doesn't define interesting methods.. so MS added extension methods IEnumerable<string> cities = new[] { "Ghent", "London", "Las Vegas", "Hyderbad" }; foreach (var city in cities) { Console.WriteLine(city); } }


Utility class - old way of doing it:

class Program { static void Main() { var date = new DateTime(2002, 8,9); int daysTillEndOfMonth = DateUtilities.DaysToEndOfMonth(date); Console.WriteLine(daysTillEndOfMonth); } } public static class DateUtilities { public static int DaysToEndOfMonth(DateTime date) { return DateTime.DaysInMonth(date.Year, date.Month) - date.Day; } }

By adding this we have an extension method.

class Program { static void Main() { var date = new DateTime(2002, 8,9); // Using an extension method int daysTillEndOfMonth = date.DaysToEndOfMonth(); Console.WriteLine(daysTillEndOfMonth); } } public static class DateUtilities { public static int DaysToEndOfMonth(this DateTime date) { return DateTime.DaysInMonth(date.Year, date.Month) - date.Day; } }

Compiler trick.  Makes the syntax nice. Extension method needs to be in the same namespace.

using System; using System.Collections.Generic; using Extensions; namespace Grades { class Program { static void Main() { // Can hide anything behind IEnumerable eg a database // doesn't define interesting methods.. so MS added extension methods IEnumerable<string> cities = new[] { "Ghent", "London", "Las Vegas", "Hyderbad" }; // Take this datasource, and give me all citites that start with L IEnumerable<string> query = cities.StringThatStartsWith("L"); foreach (var city in query) { Console.WriteLine(city); } } } } namespace Extensions { public static class FilterExtensions { // Extension method for IEnumerable<string> // Data source is IEnumerable<string> public static IEnumerable<string> StringThatStartsWith(this IEnumerable<string> input, string start) { foreach (var s in input) { if (s.StartsWith(start)) { // builds an IEnumerable yield return s; } } } } }

Implementing a simple extension method on IEnumerable<string>
This is the way that LINQ operators are defined.
static void Main() { // Can hide anything behind IEnumerable eg a database // doesn't define interesting methods.. so MS added extension methods IEnumerable<string> cities = new[] { "Ghent", "London", "Las Vegas", "Hyderbad" }; // A very generic operator..need to look at lambda expressions. cities.Where() // Take this datasource, and give me all citites that start with L IEnumerable<string> query = cities.StringThatStartsWith("L"); foreach (var city in query) { Console.WriteLine(city); } }

Lambda Expressions

Making more flexible with a delegate.. So can have an IEnumerable<T>

class Program { static void Main() { IEnumerable<string> cities = new[] { "Ghent", "London", "Las Vegas", "Hyderbad" }; // More flexible, as have a Filter method that can take delegates // that point to other things IEnumerable<string> query = cities.Filter(StringTheStartWithL); foreach (var city in query) { Console.WriteLine(city); } } static bool StringTheStartWithL(string s) { return s.StartsWith("L"); } } public static class FilterExtensions { public static IEnumerable<T> Filter<T> (this IEnumerable<T> input, FilterDelegate<T> predicate) { // foreach item in the input, invoke the predicate (method) // if predicate returns true, add to IEnumerable returning foreach (var item in input) { if (predicate(item)) { // builds an IEnumerable yield return item; } } } } public delegate bool FilterDelegate<T>(T item);


A more flexible approach than writing an extension method for each case
// C#2 Anonymous delegate IEnumerable<string> query = cities.Filter(delegate(string item) { return item.StartsWith("L"); });

This does exactly the same – don’t need a named method.  Can inline it.  A delegate calling an anonymous method.

Goes to operator

// Lambda expression.. LHS is signature of the method (takes a string - type inference) // Body returns a bool of item.StartsWith("L") IEnumerable<string> query = cities.Filter(item => item.StartsWith("L")); foreach (var city in query) { Console.WriteLine(city); }

Lambdas are the way to write delegates in C#3 and above

Func

Passing around small snippets of information to express how to perform an operation – very interesting!

Func is a generic type which encapsulates delegates (callable code)

// Delegate that takes an integer as a parameter, and returns a bool //Func<int, bool> Func<int, int> square = x => x * x; // Parameters requied for 0 or 2+ parameters Func<int, int, int> add = (x, y) => x + y; Console.WriteLine(square(3)); Console.WriteLine(add(3,4)); // Action is just like Func with no return value Action<int> write = x => Console.WriteLine(x); write(16);


Great thing about Func is we no longer need to define delegates
public static class FilterExtensions { // By using Func<T,bool> we don't need to define a delegate public static IEnumerable<T> Filter<T> (this IEnumerable<T> input, Func<T,bool> predicate) { // foreach item in the input, invoke the predicate (method) // if predicate returns true, add to IEnumerable returning foreach (var item in input) { if (predicate(item)) { // builds an IEnumerable yield return item; } } } public static IEnumerable<T> Filterx<T> (this IEnumerable<T> input, FilterDelegate<T> predicate) { // foreach item in the input, invoke the predicate (method) // if predicate returns true, add to IEnumerable returning foreach (var item in input) { if (predicate(item)) { // builds an IEnumerable yield return item; } } } } public delegate bool FilterDelegate<T>(T item);

Using the inbuilt extension method which is just like above using a Func<T>
IEnumerable<string> query = cities.Where(city => city.StartsWith("L")) .OrderByDescending(city => city.Length);

Start of Funcs and Expressions.

| | #