The power of closures in C# 2.0
Martin Fowler (obligitary Fowlbot namedrop) recently blogged about the power of closures in languages that support them. It’s worth remembering that C# 2.0 has true closure support in the form of anonymous delegates. This includes reading and modifying variables outside the context of the closure – unlike Java’s anonymous inner classes.
Just for kicks, I’ve rewritten all of the examples Martin’s Ruby examples in C# 2.0. This makes use of the improved APIs in .NET 2.0 pointed out by Zohar.
Ruby | C# 2.0 |
def managers(emps) return emps.select {|e| e.isManager} end |
public List<Employee> Managers(List<Employee> emps) { return emps.FindAll(delegate(Employee e) { return e.IsManager; } } |
def highPaid(emps) threshold = 150 return emps.select {|e| e.salary > threshold} end |
public List<Employee> HighPaid(List<Employee> emps) { int threshold = 150; return emps.FindAll(delegate(Employee e) { return e.Salary > threshold; }); } |
def paidMore(amount) return Proc.new {|e| e.salary > amount} end |
public Predicate<Employee> PaidMore(int amount) { return delegate(Employee e) { return e.Salary > amount; } } |
highPaid = paidMore(150) john = Employee.new john.salary = 200 print highPaid.call(john) |
Predicate<Employee> highPaid = PaidMore(150); Employee john = new Employee(); john.Salary = 200; Console.WriteLine(highPaid(john)); |
The code difference between the languages isn’t that difference. The C# 2.0 code is obviously longer (though not a lot) because:
- C# 2.0 is staticly typed (let’s not get started on the static vs dynamic debate).
- C# 2.0 requires the ‘delegate’ keyword.
- Ruby allows you to ignore the ‘return’ keyword.
You can try this stuff out yourself by playing with Visual C# Express.