C# 3 in .NET 3.5 got a number of handy new language features, but the
one I'm enjoying the most at the moment is the addition of the =>
operator (otherwise know as lambda). While this operator does not add
any new functionality to the language, it is a great piece of syntactic
sugar.
So what does this syntactic sugar buy us? Well, in .NET 2.0, writing
anonymous functions inline was a very verbose process. The code often
looked ugly, and many times where anonymous methods would have served me
perfectly well, I resorted to giving the function a name just to make
the code look cleaner. No more! With the introduction of the =>
operator in .NET 3.5, anonymously inline functions now have a very clean
look. It is not as clean as some other languages out there (scheme, for
instance), but it is more than enough to make anonymous functions feel
like they belong in your code, instead of looking like eyesores.
So enough of me yammering on about touchy-feely thing like 'clean code'.
Lets see this operator in action. Below we have a Fold method in C#
(actually the same exact code from a tutorial the other day on the
paramskeyword). It
takes a delegate that should take in 2 integers and return an integer
value. That delegate will be 'folded' over the other parameters to the
Fold
function, and a single integer value will be returned.public delegate int FoldIntDelegate(int a, int b);
public int Fold(FoldIntDelegate fid, params int[] list)
{
int result = 1;
foreach (int i in list)
result = fid(result, i);
return result;
}
So first, lets take a look at the verbose way of using this function. We
explicitly create a
FoldIntDelegate
to pass into Fold
, and then pass
in a bunch of ints for Fold
to work over.int val = Fold(new FoldIntDelegate(delegate(int a, int b) { return a * b; }),
1, 3, 5, 7, 9);
That is pretty ugly, don't you think? Well, with .NET 2.0, we didn't
quite have to write all that out. The
FoldIntDelegate
can be created
implicitly:int val = Fold(delegate(int a, int b) { return a * b; }, 1, 3, 5, 7, 9);
But that still is pretty verbose. Now look at all you have to write in
.NET 3.5:
int val = Fold((a, b) => a * b, 1, 3, 5, 7, 9);
A very verbose 40 character inline method declaration gets
trimmed by over half to a slim 15 character one. You no longer need to
use the word delegate, you no longer need to declare the types of the
parameters to the function (since they are already declared up where we
said what a
FoldIntDelegate
actually was), and in certain cases we can
get rid of curly-braces, parentheses, and the use of the 'return'
keyword.
Here is another example:
List<int> list = new List<int>();
//The list gets populated with values
List<int> matches = list.FindAll(val => val != 9);
The
FindAll
function takes a Predicate<int>
delegate, and with the
lambda operator, it is real easy to create such a delegate. Since the
Predicate<int>
only takes one argument, we can even leave out the
parentheses around the argument block.
Both examples we looked at so far only had one statement in the body of
the anonymous function. This let us get away with not using curly braces
or the
return
keyword. When there is more than one statement, we end
up needing them again. For instance:List<int> list = new List<int>();
//The list gets populated with values
List<int> matches = list.FindAll(val => {val = val * val; return val != 9; });
So once the body starts becoming more complex, it starts becoming
verbose again. And yes, I know that could have been condensed down to a
single statement - I just needed something to use as an example.
So there you go, the basic uses of the new lamdba operator in C# for
.NET 3.5. I can already tell that it has the potential to change how I
write C# code for certain situations, because of how much cleaner the
end result feels - hopefully, all of you are enjoying this new operator
as much as I am.
Comments
Post a Comment