Closures in C# 3.0 and 3.5

This month’s Melbourne Patterns Group meeting included discussions on functional programming.  There were some topics and terms used in the discussion that encouraged me to do more research.

One of the terms I wanted to understand better was “closures”.  In the demonstration, I was familiar with the usages (like anonymous delegates in C# or blocks from Smalltalk), but I wanted to learn more.  My investigation led me to a relatively old post on the topic from Martin Fowler.  At the bottom of his article is another reference to the C# implementation of closures, based on C# 2.0.

As these articles were written in 2004, C# has since added more support for closures in C# 3.0 with lamba expressions, and again with LINQ and extension methods in 3.5.  I found it interesting to rewrite the same examples in both C# 3.0 and 3.5:

Example 1 – List of Employees who are Managers

Fowler’s Original Example in Ruby

def managers(emps)
  return emps.select {|e| e.isManager}
end

C# 2.0 Example from Walnes

public List<Employee> Managers(List<Employee> emps)
{
    return emps.FindAll(
        delegate(Employee e)
        {
            return e.IsManager;
        }
    );
}

C# 3.0

We can now replace the anonymous delegate with a smaller lamba expression:

public List<Employee> Managers(List<Employee> emps)
{
    return emps.FindAll(e => e.IsManager);
}

LINQ and 3.5

We can now use the extension methods on IEnumerable<T> from which List<T> derives.  In this case, the Where method is appropriate.

** ToList( ) is only required if you want to maintain the return type as List<Employee>.  Otherwise, it is probably more appropriate to change to IEnumerable<Employee> here.  [Update: see this post for more differences regarding these return types.]

public List<Employee> Managers(List<Employee> emps)
{
    return emps.Where(e => e.IsManager).ToList();
}

Now, in 3.5, the C# code is nearly identical in structure and clarity as the orginal ruby example.

Example 2 – referring to a local variable in the closure block

Fowler’s Original Example in Ruby

def highPaid(emps)
  threshold = 150
  return emps.select {|e| e.salary > threshold}
end

C# 2.0 Example from Walnes

public List<Employee> HighPaid(List<Employee> emps)
{
    int threshold = 150;
    return emps.FindAll(delegate(Employee e)
    {
        return e.Salary > threshold;
    });
}

C# 3.0

Again, we can now replace the anonymous delegate with a smaller lamba expression:

public List<Employee> HighPaid(List<Employee> emps)
{
    int threshold = 150;
    return emps.FindAll(e => e.Salary > threshold);
}

LINQ and 3.5

Again, we can now use the extension methods on IEnumerable<T> from which List<T> derives.  In this case, the Where method is appropriate.

** Again, ToList( ) is only required if you want to maintain the return type as List<Employee>.  Otherwise, it is probably more appropriate to change to IEnumerable<Employee> here.  [Update: see this post for more differences regarding these return types.]

public List<Employee> HighPaid(List<Employee> emps)
{
    int threshold = 150;
    return (List<Employee>) emps.Where(e => e.Salary > threshold).ToList();
}

Now, in 3.5, the C# code is nearly identical in structure and clarity as the orginal ruby example.

Example 3 – returning a closure from a method

Fowler’s Original Example in Ruby

def paidMore(amount)
  return Proc.new {|e| e.salary > amount}
end

C# 2.0 Example from Walnes

public Predicate<Employee> PaidMore(int amount)
{
    return delegate(Employee e)
    {
        return e.Salary > amount;
    };
}

C# 3.0

Again, we can now replace the anonymous delegate with a smaller lamba expression:

public Predicate<Employee> PaidMore(int amount)
{
    return e => e.Salary > amount;
}

There would be no change to the above in 3.5 (same as C# 3.0) here.

Example 4 – Create a function using the closure & assign to a variable

Fowler’s Original Example in Ruby

highPaid = paidMore(150)
john = Employee.new
john.salary = 200
print highPaid.call(john)

C# 2.0 Example from Walnes

Predicate<employee> highPaid = PaidMore(150);
Employee john = new Employee();
john.Salary = 200;
Console.WriteLine(highPaid(john));

There would be no change to the above in 3.0 or 3.5 (same as C# 2.0) here.

Download source here to see complete C# examples.

About these ads

One thought on “Closures in C# 3.0 and 3.5

  1. Pingback: IEnumerable and Lazy Evaluation « Chris Melinn

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s