Archive for the ‘lambda’ tag
C#'s Lambda ForEach: Only on Lists?
One of my favourite things introduced into C# recently is the new ForEach method which can be applied to (apparently only!) lists.
Last week we had a situation where we wanted to make use of the ForEach method on an IDictionary which we were using to store a collection of Selenium clients.
1 | IDictionary<string, ISelenium> seleniumClients = new Dictionary<string, ISelenium>(); |
We wanted to write a piece of code to exit all of the clients when our tests had completed. We thought the following would do the trick:
1 | seleniumClients.Values.ForEach(client => client.Stop()); |
The problem is that code doesn't actually compile!
'seleniumClients.Values' returns an ICollection which extends IEnumerable so we thought ForEach should be available.
We eventually got around the problem by putting the collection into a list and then applying the ForEach method but it seems like there should be a better way to do this.
1 | new List<ISelenium>(seleniumClients.Values).ForEach(client => client.Stop()); |
Is there?
Lambda in C#: Conciseness v Readability
One of the things I really disliked when I first came across C# 3.0 code was lambda functions.
At the time I remember speaking to my Tech Lead and expressing the opinion that they were making the code harder to understand and were valuing conciseness over readability.
After a week of reading about the new C# features and understanding how they worked the code was now more readable to me and a lot of the boiler plate code that I had come to expect was no longer necessary.
My favourite example of the power of lambda is when we want to iterate through a collection of items and apply the same operation to every item in the collection.
In normal C# we might do this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | public class Foo { private String bar; private String baz; public Foo(String bar, String baz) { this.bar = bar; this.baz = baz; } public override string ToString() { return string.Format("{0} - {1}", bar, baz); } } |
1 2 3 4 5 6 7 8 9 | var foos = new List<Foo>(); foos.Add(new Foo("bar1", "baz1")); foos.Add(new Foo("bar2", "baz2")); var fooString = new List<String>(); foreach (var foo in foos) { fooString.Add(foo.ToString()); } |
Using the power of C# 3.0 we can change that last for each statement to read something like this:
1 | var fooString = foos.Select(f => f.ToString()); |
This is much more concise but I think the judgement on its readability depends on one's understanding of the language feature.
One idea I am considering trying is using methods which describe more clearly what the lambda function is doing. This is an idea I came across from Kris Kemper's post about using similar Ruby language features.
In the example I gave perhaps wrapping the foo.Select(…) in a method called 'ConvertToStringRepresentation()' might make it more readable – it's clearly up for debate though.
When I was learning how lambda worked I found it useful to be able to do the comparison of how you would write code without it and being able to compare that with how you could do it with lambda. I also found having some understanding of how Ruby blocks worked made it easier as well.
Clearly having powerful language features means that a language is much easier to abuse but I think if used sensibly then readability and conciseness need not be mutually exclusive.