Skip to content

Instantly share code, notes, and snippets.

@joladev
Last active December 25, 2015 20:49
Show Gist options
  • Save joladev/7038347 to your computer and use it in GitHub Desktop.
Save joladev/7038347 to your computer and use it in GitHub Desktop.
LINQ 101
// Getting some cruft out of the way
public class le{
// Set up a Person class for use in examples.
public class Person{ public string Name { get; set; } }
public static void Main(string[] args){
// A gentle introduction to LINQ, language integrated queries,
// in C#. To start off, let's do some disambiguation.
// This is a lambda expression
// s => s == "hello"
// These are extension methods exposed by LINQ
// Select, Where, GroupBy, OrderBy, etc
// This is query syntax, a syntactic sugar
// over the LINQ extension methods.
// from l
// where l.name == "ada"
// select l
//
// For this tutorial, we'll be focusing on LINQ
// methods directly, using lambda expressions.
//
// Data for examples.
var persons = [
new Person() { Name="Ada" },
new Person() { Name="Haskell" }
];
//
// SELECT
//
// We begin by taking a look at "select".
// This is an extension method which attaches
// itself to lists and listlike things (IEnumerable).
//
// It corresponds to "select" in SQL and "project"
// in relational algebra. Here are some examples:
var names = persons.Select(p => p.Name);
// => ["Ada", "Haskell"]
var uppers = names.Select(n => n.ToUpperCase());
// => ["ADA", "HASKELL"]
// LINQ methods lend themselves well to chaining,
// as each method returns a modified version of
// its input. Combining the two lines from above:
var combo = persons.Select(p => p.Name)
.Select(n => n.ToUpperCase());
// => ["ADA, "HASKELL"]
// You can also do mostly pointless things like
var wtf = person.Select(p => "Tesla");
// => ["Tesla", "Tesla"]
// Essentially, select, and all the other LINQ
// methods, act as transformations upon data.
// Select takes a lambda expression (or delegate)
// and applies this for each value in the list.
// On the first pass, p is "Ada". When we apply
// our transformation, this is replaced with
// "Tesla". Select continues to iterate through
// the entire list, applying the lambda expression
// on each value and gathering the results into
// a new list, which it returns.
// This means LINQ doesn't change the list you
// call it on. It always returns new lists. This
// has some nice implications for concurrency
// and parallelism and tends to lead to more
// expressive code.
//
// WHERE
//
// Moving on from projections, let's take a look
// at the filtering method. It corresponds to
// where in SQL and select in relational algebra.
var ada = persons.Where(p => p.Name == "Ada");
// => ["Ada"]
// Where takes a lambda that returns a boolean.
// This is commonly known as a "predicate".
// Any boolean expression serves as a predicate.
// Where can also be chained with Select.
var adaString = persons.Select(p => p.Name)
.Where(s => s == "Ada");
// => ["Ada"]
var haskellString = persons.Select(p => p.Name)
.Where(s => s != "Ada");
// => ["Haskell"]
//
// Brief interlude: CLOSURES
//
// C# also handles closures for lambda expressions.
// This is something that you probably have used,
// and normally "just works". But knowledge is
// power, so let's take a look.
var target = "Haskell";
var haskell = persons.Where(p => p.Name == target);
// => ["Haskell"]
// So what's so impressive about that?
// If we take a closer look at the lambda.
// p => p.Name == target
// There are two variables involved: p and target.
// p is supplied through the anonymous function,
// or delegate, parameter. It is bound to the
// scope of the lambda in the way we are used to.
// But how does target get in there?
// END
}}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment