Insights and outlooks on software development

S'true

Fluent interfaces by lambdas in C#

Friday, November 28, 2008 by Thomas L

This thursday and friday, I've been in the lovely small town of Karlskrona and attended a Domain-Driven Design course/seminar with Jimmy Nilsson, arranged by my employer, Softhouse. One part of the workshop was on fluent interfaces; and I found out that it's actually quite unknown that you can do stuff like this in C# (I know, it's not the best of examples, but I'm writing this on a friday night.)

Vodka v = new Vodka(4.centiliters());
Centiliter c = v.Centiliters;
Assert.AreEqual(4, c.number);

Notice the "4.centiliters" construct. To make it work I use an extension method on int to construct the Centiliter class:

public static Centiliter centiliters(this int numberOfCentiliters)
{
  return new Centiliter(numberOfCentiliters);
}

This would of course look even better in ruby, its dynamic nature lends itself quite well to building fluent interfaces. But some parts of building fluent interfaces are actually possible to steal from ruby. Like for instance the idiomatic block example:

5.times do
  puts "hello world!"
end

...is possible to implement in C#:

5.Times(() => Console.WriteLine("hello world!"));

The syntax is quite much worse than ruby's; it has too much of noise in the form of parantheses, semi colons and the rocket operator (" => "), but the C# team has definitely made one step towards a more usable language as a whole by adding the lambda construct to the language. I'd love the possibility to remove "() =>" from the lambda above (please, pretty please, with sugar on top, Anders?), since then the syntax would be

5.Times(Console.WriteLine("hello world!"));

The extension method I use to get the syntax above looks like this:

public static void Times(this int number, Action block)
{
  for (int i = 0; i < number; i++)
    block();
}

I know that the examples above are quite unusable, but there are ideas up there that actually is usable; the Machine.Specifications (or MSpec for short) uses lambdas to do its thing. And the one big part that is intimidating everyone new to MSpec is the "() =>" syntax. If we could get rid of that, it'd be easier to introduce BDD to the .NET community.

Technorati Tags: ,,,

Filed under , having  

0 kommentarer: