Wednesday, July 30, 2008

Lambda Expressions Extension Methods and LINQ in C# 3.0

The idea behind anonymous methods it to write methods inline to the code so you don't have to go through the trouble of declaring a formal named method. They are mainly used for small methods that don't require any need for reuse.

Instead of declaring a separate method IsAbe to find Abe in a list of strings:

 
class Program
{
  static void Main(string[] args)
  {  
  List names = new List();
  names.Add("Dave");
  names.Add("John");
  names.Add("Abe");
  names.Add("Barney");
  names.Add("Chuck");
  string abe = names.Find(IsAbe);
  Console.WriteLine(abe);
  }
  public static bool IsAbe(string name)
  {
  return name.Equals("Abe");
  }
}

 

You can declare an anonymous method inline to save you the trouble:

 
class Program
{
  static void Main(string[] args)
  {  
  List names = new List();
  names.Add("Dave");
  names.Add("John");
  names.Add("Abe");
  names.Add("Barney");
  names.Add("Chuck");
  string abe = names.Find(delegate(string name)
  {
  return name.Equals("Abe");
  });
  Console.WriteLine(abe);
  }
}

 

It can get a lot fancier than that, but that is basically the gist. Declare the method inline to the code for easy stuff not needing reuse, because it saves some typing and puts the method closer to where it is being used which helps with maintenance.
Lambda Expressions

Lambda Expressions make things even easier by allowing you to avoid the anonymous method and that annoying statement block:

 
class Program
{
  static void Main(string[] args)
  {  
  List names = new List();
  names.Add("Dave");
  names.Add("John");
  names.Add("Abe");
  names.Add("Barney");
  names.Add("Chuck");
  string abe = names.Find((string name)
  => name.Equals("Abe"));
  Console.WriteLine(abe);
  }
}

 

Because Lambda Expressions are smart enough to infer variable types, I don't even have to explicity mention that name is a string above. I can remove it for even more simplicity and write it as such:

 
class Program
{
  static void Main(string[] args)
  {  
  List names = new List();
  names.Add("Dave");
  names.Add("John");
  names.Add("Abe");
  names.Add("Barney");
  names.Add("Chuck");
  string abe = names.Find(name =>
  name.Equals("Abe"));
  Console.WriteLine(abe);
  }
}

 

Now there is no particular reason why I have to use name as my variable. Often developers will use 1 character variable names in Lambda Expressions just to keep things short. Here we replace name with p and all works the same.

 
class Program
{
  static void Main(string[] args)
  {  
  List names = new List();
  names.Add("Dave");
  names.Add("John");
  names.Add("Abe");
  names.Add("Barney");
  names.Add("Chuck");
  string abe = names.Find(p => p.Equals("Abe"));
  Console.WriteLine(abe);
  }
}

 
Lambda Expressions Using a Customer Class

I used a list of strings above, but you can just as easily use a list of objects to do the same thing. I will take an abbreviated form of a Customer Class:

 
public class Customer
{
  public int Id;
  public string Name;
  public string City;
  public Customer(int id, string name, string city)
  {
  Id = id;
  Name = name;
  City = city;
  }
}

 

and now use Lambda Expressions to find a particular Customer with a name of "Abe".

 
class Program
{
  static void Main(string[] args)
  {  
  List customers = new List();
  customers.Add(new Customer(1,"Dave","Sarasota"));
  customers.Add(new Customer(2,"John","Tampa"));
  customers.Add(new Customer(3,"Abe","Miami"));
  Customer abe = customers.Find(c =>
  c.Name.Equals("Abe"));
  }
}

 

Again, we could make things more obvious by explicity saying that c is of type Customer, but I wouldn't bet on many people doing it :) You could write the above as follows:

 
class Program
{
  static void Main(string[] args)
  {  
  List customers = new List();
  customers.Add(new Customer(1,"Dave","Sarasota"));
  customers.Add(new Customer(2,"John","Tampa"));
  customers.Add(new Customer(3,"Abe","Miami"));
  Customer abe = customers.Find((Customer c) =>
  c.Name.Equals("Abe"));
  }
}

 
Combining Extension Methods and Lambda Expressions for Help In Finding Our Customer

Let's say we have a custom CustomerCollection Class not within our control that doesn't provide us an easy way to find a Customer:

 
public class CustomerCollection :
  IEnumerable
{
  IEnumerable _customers;
  public CustomerCollection(IEnumerable
  customers)
  {
  _customers = customers;
  }
  public IEnumerator GetEnumerator()
  {
  foreach (Customer customer in _customers)
  yield return customer;
  }
  System.Collections.IEnumerator System.Collections
  .IEnumerable.GetEnumerator()
  {
  return _customers.GetEnumerator();
  }
}

 

Let's add an Extension Method to the CustomerCollection Class, called GetCustomer:

 
public static class CustomerExtensions
{
  public static Customer GetCustomer(this
  CustomerCollection customers,
  Predicate isMatch)
  {
  foreach (Customer customer in customers)
  if (isMatch(customer))
  return customer;
  return null;
  }
}

 

And now, we can use the CustomerCollection Class to easily find Abe like:

 
class Program
{
  static void Main(string[] args)
  {  
  CustomerCollection collection = GetCustomers();  
  // Using my GetCustomer Method Extension...
  Customer abe = collection.GetCustomer(c =>
  c.Name.Equals("Abe"));
  }
   
  // Pretend We Don't See This :)
  static CustomerCollection GetCustomers()
  {
  List customers = new List();
  customers.Add(new Customer(1,"Dave","Sarasota"));
  customers.Add(new Customer(2,"John","Tampa"));
  customers.Add(new Customer(3,"Abe","Miami"));
   
  return new CustomerCollection(customers);
  }
}

 
But This Is LINQ!

But, of course, since CustomerCollection implements IEnumerable, in this case, IEnumerable, screw the Extension Methods and just use LINQ:

 
class Program
{
  static void Main(string[] args)
  {  
  CustomerCollection collection = GetCustomers();  
  // LINQ
  var abe = collection.Single(c =>
  c.Name.Equals("Abe"));
  }
   
  // Pretend We Don't See This :)
  static CustomerCollection GetCustomers()
  {
  List customers = new List();
  customers.Add(new Customer(1,"Dave","Sarasota"));
  customers.Add(new Customer(2,"John","Tampa"));
  customers.Add(new Customer(3,"Abe","Miami"));
   
  return new CustomerCollection(customers);
  }
}

Tuesday, July 29, 2008

When ASP.NET hit the street a couple of years ago, it was a real eye-opener. Microsoft's tool for creating dynamic, server side web applications introduced Web Forms, a feature with the same rapid drag and drop convenience enjoyed by Visual Basic developers, along with a method for creating XML-based web services. ASP.NET was more than an upgrade of Active Server Pages it was a quantum leap ahead. Now Microsoft has a new version of ASP.NET as part of its upcoming next generation release of the Visual Studio .NET development platform. ASP.NET 2.0 is already available in beta release, and web developers are anxious to get a good look at it. That's exactly what our new Developer's Notebook allows you to do. More than just an introduction to ASP.NET 2.0, this practical guide acquaints you with all of the new features through nearly 50 hands-on projects. Each one places emphasis on changes in the new release that can increase productivity, simplify programming tasks, and help you add functionality to your applications. For example, ASP.NET 2.0 includes master pages, themes, and skins so you can build applications with a consistent page layout and design. Other changes allow for the automatic creation of web pages for use on mobile devices, while wizards and controls allow you to perform frequent tasks (like data access) without having to write a single line of code. ASP.NET 2.0: A Developer's Notebook also includes suggestions for further experimentation, links to on-line documentation, and practical notes and warnings from the author regarding changes to the new version. The new Developer's Notebooks series from O'Reilly offers an in-depth first look at important new tools for software developers. Emphasizing example over explanation and practice over theory, they focus on learning by doing you'll get the goods straight from the masters, in an informal and code-intensive style. If you want to get up to speed on ASP.NET 2.0 before its official release, this all lab, no lecture book will get you there.