first glance at lambda functions in c# 3.0

When I first heard about lambda functions in c# 3.0, I were a bit sceptical, since the syntax is like nothing else I have seen.

I am still sceptical, but I can see places where they have their use, like in very simple selects from lists, simple string manipulations etc.

Like
	    string[] abs = new string[] { "Ab", "ab", "aB", "AB" };

            var abSelected = abs.Where(str => str == "ab");

            foreach (string p in abSelected)
            {
                Console.WriteLine(p);
            }

            var allAbs = abs.Where(str => str.ToLower() == "ab");
            foreach (string p in allAbs)
            {
                Console.WriteLine(p);
            }
Which shows an array of strings, where we first select those that matches "ab", lowercase, and then writes each one found out. Then it selects the same again, but ignores the case, and more or less selects everything.

Or a simple string manipulation:

	    var allCAPS = abs.Select(cap => cap.ToUpper());
            Console.WriteLine("ab all upper case\r\n");
            foreach (string p in allCAPS)
            {
                Console.WriteLine(p);
            }
Which basically converts all the strings to uppercase. In this example pretty useless, but it could be other string manipulations done.

objects are more or less the same syntax. Consider the following simple classes:

 public enum Sex
 {
     Female,
     Male,
     YesPlease
 }

 public class Person
 {
     public string Name
     {
         get;
         set;
     }

     public int Age
     {
         get;
         set;
     }

     public Sex Sex
     {
         get;
         set;
     }

     
 }
And the following snippets of code:

 List<Person> people = new List<Person>();
 
 Person person = new Person();
 person.Name = "Bjørn Smith";
 person.Age = 34;
 person.Sex = Sex.Male;
 people.Add(person);

 person = new Person();
 person.Name = "Female beauty hungry for sex";
 person.Age = 35;
 person.Sex = Sex.YesPlease;
 people.Add(person);

 person = new Person();
 person.Name = "Female beauty";
 person.Age = 18;
 person.Sex = Sex.Female;

 people.Add(person);

 person = new Person();
 person.Name = "Female blonde";
 person.Age = 25;
 person.Sex = Sex.Female;

 people.Add(person);

 person = new Person();
 person.Name = "Female brunette";
 person.Age = 38;
 person.Sex = Sex.Female;

 people.Add(person);
First a simple setup, to get some data to work with. I know the dataset is sparse, but it should be enough to show some ways of using lambda.

And then some simple queries to the list:

 Console.WriteLine("Female of all ages");
 var females = people.Where(a => a.Sex == Sex.Female || a.Sex == Sex.YesPlease);
 foreach (Person sexpartner in females)
 {
     Console.WriteLine(string.Format("{0}, {1} years", sexpartner.Name, sexpartner.Age));
 }

 Console.WriteLine("Order by age ascending"); females = people.Where(a => a.Sex == Sex.Female || a.Sex == Sex.YesPlease).OrderBy(a => a.Age); foreach (Person sexpartner in females) { Console.WriteLine(string.Format("{0}, {1} years", sexpartner.Name, sexpartner.Age)); } //For those really hungry we only want objects with name and sex var hungry = people.Where(a => a.Sex == Sex.YesPlease).Select(hu => new { hu.Name, hu.Age }); Console.WriteLine("Hungry only"); foreach (var femalehungry in hungry) { Console.WriteLine(string.Format("{0}, {1} years", femalehungry.Name, femalehungry.Age)); }

First query is just selecing all Person objects that have Sex as Female or YesPlease.

Please note the "strange" syntax of creating the "query" object by doing a: a => a.Sex ==  Sex.Female, which is exately the same as an anonymous delegate like delegate(string a) {return a.Sex == Sex.Female;}. I tend to like the last anonymous delegate more, since in my eyes its obvious what it does, but I'm sure that in time, I will embrace lambda functions where they make sense.

Second query is basically the same as the first one, but with the twist that we are ordering the list by Age ascending, just by doing a .OrderBy(a => a.Age), thats quite nifty I think, and if you compare to anonymous delegates, you would have had to do something like the following to have the same result:

 List<Person> femalePeople = people.FindAll(delegate(Person p)
 {
     return p.Sex == Sex.Female;
 }).Sort(delegate(Person ps1, Person ps2)
 {
     return ps1.Age.CompareTo(ps2.Age);
 });
So when you compare the two blocks of code, I see the benefit of lambda functions, but I still think they clutter the code, anonymous delegates easier to understand, but then again, it might just need some getting used to :)


The last select to the people list is basically the same, but we only select those that have YesPlease as Sex, and we create a new class on the fly with only two Properties, Name and Sex. Thats less usefull if you ask me, since you cannot return an object to the caller of a method, and get the type safety etc. But naturally you can manipulate the newly created objects, and you get intellisense and all the works, thats quite nice :)

This was my first glance at lambda functions, and it might be useful, I still need to see the definitive proof of their usefullness, in particular the feature to create anonymous types on the fly, but I am open to enlightenment :)

multi-cast delegates and Predicate<T>

Since Predicate<T> that is used for finding stuff in a generics list is in fact a multi-cast delegate, I thought it might be possible to chain several Predicates to simplify multiple requirements for the elements returned.

Consider the following code:

Predicate<int> greaterThan5 = delegate(int x) { return x > 5; };
Predicate<int> lessThan10 = delegate(int x) { return x < 10; };

It would be cool if it would be possible to chain them, by doing a simple:

Predicate<int> combined = lessThan10 + greaterThan5;

And then:

List<int> resulting = allInts.FindAll(combined);

Unfortunately it dosen't work, or more precicely, it is only the last delegate that gets invoked.

It seems like MS did not envision people wanting to use multi-cast delegates for their predicates, and when looking at the List.FindAll implementation, its very clear, since it only invokes the delegate as it were a single cast one:

public List<T> FindAll(Predicate<T> match)
{
    if (match == null)
    {
        ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
    }
    List<T> list = new List<T>();
    for (int i = 0; i < this._size; i++)
    {
        if (match(this._items[i]))
        {
            list.Add(this._items[i]);
        }
    }
    return list;
}


So unfortunately you still need to do the old fashion way:

List<int> resulting = allInts.FindAll(lessThan10).FindAll(greaterThan5);

Lets hope they change it in c# 3.0

Delegates

Some years ago, when someone mentioned delegates I would shudder, and think back of all the times when I had tried to use them to something useful, and All I could think of at the time was to use them for events that other objects could subscribe to. This is also a nice feature, but when you think about it delegates is so much more.

I have started using delegates more heavily, and primarily to do Lazy Loading of data from a database. Lazy Loading is a technique where you only load the data when the application need it.  Lets say you have a class Customer, with a lot of properties, including an Orders collection. Instead of loading all orders and all other data that is related to the Customer, why not just load the data when the application makes a request for it, by invoking the get method of the Orders collection.

People would perhaps argue that it would require for the business objects to know the database structure, or if done a little more clever, need a reference to a Data Access Layer, but no, thats not neccesary, since you can use delegates for it.

consider the following delegate:

public delegate List<T> LoadDataDelegate<T>();


This delegate states that it will return a list of objects of type T.

okay then consider the following class

public class Customer
{

    /// <summary>
    /// Creates a new instance of the Customer class
    /// </summary>
    /// <param name="ordersDelegate"></param>
    public Customer(LoadDataDelegate<Order> ordersDelegate)
    {
        this.ordersDelegate = ordersDelegate;
    }

    private LoadDataDelegate<Order> ordersDelegate;

    private List<Order> orders;
    /// <summary>
    /// Gets a List of orders for the current Customer
    /// </summary>
    public List<Order> Orders
    {
        get
        {
            if (orders == null)
            {
                orders = ordersDelegate();
            }
            return orders;
            }
    }
   
    
}


And the following Mock data layer

public class DAL
{
    public List<Order> GetAllOrdersForCustomer(long customerID)
    {
        string sql = "select * from orders where customer_id=@customer_id";
        //etc
        //load into list
        }

        public Customer GetCustomer(long customerID)
        {
            Customer c = new Customer(delegate() { return GetAllOrdersForCustomer(customerID); });
            //load other data from the database

            return c;
        }
}


These two classes and the delegates, show a very simple way of using delegates for something intelligent and create an object that is capable of loading data from the database on demand, without knowing anything about Datalayers, SQL or anything else.

Nice right :)

Consider implementing all methods that can create, read, update and delete an object as delegates and all you would ever need to expose to your application is the business objects, and perhaps a few factory methods that could create new instances of objects with the delegates assigned to actual methods in your data layers :)