I was just reading Mike Stall's blog Fun with yield, generics, foreach. He discusses using enumeration with yield and generics. The example he uses is a heterogenous array object[] list = new object[] {1,2, "abc", 5f, "def" }; and he needs to print all the strings in it. The simple solution in C#1.x is
object [] list = new Object[] { 1, 2, "abhinaba", 5f, "basu" };foreach (Object o in list) { string s = o as string; if (s == null) continue; Console.WriteLine(s); }
{
}
Initially I was kind of opposed to the whole idea of LINQ. I think this is the mental adoption blocker which everyone talks about. As time is passing and I am being forced to use C#2.0 (we have not yet moved to 3.0) everyday I get the urge to use LINQ as it solves many problem so elegantly. If we use C#3.0 we can do this as follows
object[] list = { 1, 2, "abhinaba", 5f, "basu" }; foreach( var v in list.Where(x => x is string)){ Console.WriteLine(v);}
This code uses some of the new C#3.0 features. Where is a System.Query provided extension method which you can add to any collection. x => x is string is a lambda expression which is passed as the predicate to the extension method. Here type parameters of the predicate is inferred from the lambda expression.
After writing this code I just felt happy. I think the greatest achievement for any language is that it makes programmers who use it happy, what more can you ask for?
<Edit : Some additions>
I asked what more you can ask for and Theme over on the original Mike's post suggested that the foreach can be further reduced. I took the hint and cooked up the following
public delegate void Action<T>(T val);static class MyExtensions{ public static void ForEach<T>(this IEnumerable<T> list, Action<T> act) { foreach (T t in list) act(t); }} object[] list = { 1, 2, "abhinaba", 5f, "basu" }; list.Where(x => x is string).ForEach(Console.WriteLine);
act(t);
So if I have the Extension method ForEach handy in some assembly/source or if I can find the equivalent in System.Query namespace then I have reduced the solution to 2 lines. Since the whole of it is generics based and Console.WriteLine have enough overloads the solution works fine with data types other than string (like int).
I asked for more and got more. Bring on C#3.0, 2.0 is already stale and its time to replace it...