While catching up with a friend for (a very geeky) lunch the other day, a few ideas crystalised into another idea for the next version of C#.
The lambda expression syntax introduced in C# 3.0 is a brilliant step forward from the anonymous delegates of C# 2.0, but one thing has always irked me - that a lambda expression with no parameters needs to be written this way:
Clearly, you need specific syntax to identify a lambda expression, but is this really the best they could do?
I have a suggestion to make: For a parameterless lambda expression, why can’t we just write a block, surrounded by braces. So, instead of these:
We should be able to write
(And, yes, I’m aware that there are simpler ways to write those first examples, ways that are still valid C#. Bear with me, there is a point to my rambling.)
Now, let’s throw a new piece of parameter syntax sugar into the mix. Hopefully you’ll be aware of the
that allows you to write methods that take a variable number of parameters:
You can only use the
params keyword for the last parameter - the compiler will throw an error if you put it somewhere
else, or if the type given is not an array.
Let’s introduce a new keyword,
block that can only be used for the last parameters of the method, and only if those
parameter types are delegates with no parameters. The purpose of this parameter is to allow callers to put the
implementation of the block following the apparent method call, instead of within it.
If we take both of these ideas, we can change the code we write from this:
A little bit of syntactic sugar has given us a nice way to craft apparent C# extensions, that work along the lines of
But, wait, you say - when you described the
block keyword, you used the word parameters - what happens when you
block parameters in your method signature?
I’m glad you asked. ;-) In line with the way that named parameters work in C# 4.0, I suggest each block should be prefixed by the name of the parameter being supplied. How would this look?
First, we declare the method itself - perhaps one to support writing transactional programs:
Or perhaps, one that that forms part of a “design by contract” API:
So, what does this bit of syntactic sugar give us? Roll your own language extensions.
There are a few obvious ways to enhance this - such as allowing blocks to break out delegates that take parameters, but I’ll leave those as an exercise for the reader.