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.

  • Trackback are closed
  • Comments (23)
  1. Cool, but what’s with the capitalized method names? ICK!!!

    • Joe Walnes
    • September 17th, 2004

    Here is a sample comparison of anonymous delegates in C# 2.0 with anonymous inner classes in Java.

    C# 2.0

    int total = 0;
    order.EachItem(delegate(Item item) {
      total += item.Price;
    }
    Console.WriteLine(“Total of order is {0}”, total);

    Java

    final int[] total = { 0 };
    order.eachItem(new OrderBlock() {
      public void handle(Item item) {
        total[0] += item.getPrice();
      }
    });
    System.out.println(“Total of order is ” + total[0]);

    This is something I end up doing a lot, and I cringe everytime. The anonymous bloat I don’t mind so much, but the final array hack is what really gets me. This is necessary because any local variable outside the scope the of the inner must be final, so the only way to write to it is to use an array. Thankfully IDEA always automagically sorts this out for me, but it’s still confusing for someone who is later trying to understand the code.

  2. I said many times: c# 2.0 is a kind of statically typed ruby. Even the icollection apis wich gets anonimous delegates as parameters really resemble ruby’s Enumerable.

    • Pavel Tavoda
    • September 17th, 2004

    If you want use scripting languages, go with Groovy. This have very extended closure support.

    • Meitsi
    • September 17th, 2004

    “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).”

    No, not quite the right reason. C# is longer specifically because it uses manifest typing.

  3. Eeee! The code runs all over the sidebar. Unreadable even at 1024 px width!

    Try putting such code blocks in a div with the style “overflow:auto” set

    • Yuriy
    • September 18th, 2004

    just to remind that JScript supports this technique

    small sample:
    function A(D) {
    var C = 10;
    if (D == 1) {
    B = function () {
    WScript.Echo(C);
    }
    C = 11;
    }
    else
    C = 12;

    B();
    C = 13;
    }

    var
    C = 90;

    A(1);
    A();
    B();

  4. C# Version 2.0 Specification

  5. C# Version 2.0 Specification

    • Anonymous
    • September 22nd, 2004

    The example code is wrong, I think. Shouldn’t the FindAll example actually be:

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

    Note the additional round bracket and semicolon at the end of the return statement. The code doesn’t look quite so clean now, unfortunately.

    • Bill Wood
    • October 20th, 2004

    I’ve put boo versions of these examples here:
    http://docs.codehaus.org/display/BOO/Martin+Fowler%27s+closure+examples+in+boo

    Boo is a new object oriented statically typed programming language for the Common Language Infrastructure with a python inspired syntax and a special focus on language and compiler extensibility.

    http://boo.codehuas.org

    • Bill Wood
    • October 20th, 2004

    Sorry the second link above to boo should be:

    http://boo.codehaus.org/

  6. Closures in C# 2.0

    Closures in C# 2.0

    • Jay
    • April 26th, 2005

    I would like to check this out, but I can’t read the C# because it drools out into the right sidebar.

    • David Vallner
    • June 16th, 2005

    Minor note by a rubyist – the Ruby code examples don’t make use of omitting the return keyword. If you used return inside a closure, it would return from the method it was defined in.

  7. Collection closure method

  8. Collection closure method

  9. Collection closure method

  10. Collection closure method

    • Chris
    • August 14th, 2005

    Please God fix the messed up tables created by SiteMash and UnmoveableType so I can read this example.

  11. Quote:
    |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).

    Static typing is a bad excuse for longer code. It’s not obvious at
    all. Look at this Haskell example:

    f x = (\y -> x + y)

    It’s a closure (see ).

    Nevertheless Haskel is a statically typed language (see table “Type
    system cross reference list” in
    ).

    Regards
    Thomas

  12. Sorry that I’ve to post it again, but the Blog software skipped the
    URLs because of the surrounding angle brackets.

    Quote:
    |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).

    Static typing is a bad excuse for longer code. It’s not obvious at
    all. Look at this Haskell example:

    f x = (\y -> x + y)

    It’s a closure (see http://www.haskell.org/hawiki/Closure).

    Nevertheless Haskell is a statically typed language (see table “Type
    system cross reference list” in
    http://en.wikipedia.org/wiki/Dynamic_typing ).

    Regards
    Thomas

  13. Essential C# 2.0
    http://www.awprofessional.com/bookstore/product.asp?isbn=0321150775&rl=1 (sample chapter “Generics”
    Essential C# 2.0 is a clear, concise guide to C#—including the features new to C# 2.0. The book clearly presents material for beginners and experts and provides contrasts and comparisons between C# and other languages. The C# language is covered comprehensively and each important construct is illustrated with succinct code examples. Complete code examples are available online. Mark Michaelis has organized the material for quick access. Graphical “mind maps” at the beginning of each chapter show what material is covered and how each topic relates to the whole.
    Following the C# introduction, readers will learn about
    • C# primitive data types, value types, reference types, type conversions, and arrays
    • Operators and control flow, loops, conditional logic, and sequential programming
    • Methods, parameters, exception handling, and structured programming
    • Classes, inheritance, structures, interfaces, and object-oriented programming
    • Well-formed types, operator overloading, namespaces, and garbage collection
    • Generics, collections, and iterators
    • Reflection, attributes, and declarative programming
    • Threading, synchronization, and multi-threaded patterns
    • Interoperability and unsafe code
    • The Common Language Infrastructure that underlies C#

Comments are closed.
%d bloggers like this: