C# Getting Unreadable?
Mike Gunderloy remarked, in
today's Daily Grind,
"Ian Griffiths explains some of the advanced syntax of C# 3.0. I freely admit that my eyes glazed over. As far as I'm concerned, C# is now going the way of C++: it's got syntax that I will never, ever use and is well on its way to complexifying its way out of my life."
I find it interesting that people keep saying this. There was one guy at the PDC during the Linq End-To-End panel that was very convinced that C# was quickly becoming too complex, and ergo unreadable. He stated that he believed that the introduction of generics made the BCL look too much like C++’s STL and made the code produced too complex for the average developer to learn. From there, he transitioned into voicing concern over the new languages features in C# 3.0.
I, personally, can’t understand this aversion to Linq and the new C# 3.0 language features. Let’s look at the following code, shamelessly stolen from
Ian Griffith’s post. First, we’ve got the C# 2.0 anonymous methods version of it. (I’m not even going to bother reproducing the C# 1.0 version. That would be pointless. Whidbey is here, people. Get used to it.)
public static void ShowDivisible()
{
for (int d = 1; d < 10; ++d)
{
Console.WriteLine("Numbers divisible by " + d);
PrintMatchingNumbers(1, 10,
delegate(int i)
{
return (i % d) == 0;
});
}
}
Now I think we can all agree that anonymous methods are pretty cool. It saves a lot of work when constructing one time use methods just to fulfill a delegate. Also, I believe the code is more readable than it’s C# 1.0 counterpart due to the fact that I don’t have to go hunt down a method somewhere else in my codebase. I’ve got it right there in the place where I’m using it. So, having seen that, lets take a look at the C# 3.0 version of the same code.
public static void ShowDivisible()
{
for (int d = 1; d < 10; ++d)
{
Console.WriteLine("Numbers divisible by " + d);
PrintMatchingNumbers(1, 10, i => (i % d) == 0);
}
}
Now, as I said, I personally think this is much more readable. The new lambda expression syntax puts the focus more on the actual intent of the code (the fact that I only want to print out numbers where i % d == 0) than the construction of the delegate. In addition, thanks to C# 3.0’s new local variable type inference abilities, I don’t have to worry about how to construct my delegate and what the signature looks like. The compiler just knows. I get all this at the cost of…what? Learning a new => operator? If it means that I don’t have to worry about those delegate signatures anymore, then count me in. I’m a big fan of the fact that I can let the compiler worry about that for me.
What I really can’t understand is the aversion to the new language syntax for the standard query operators. They’ve introduce querying ability baked directly into the language that supports query operations over anything that implements IEnumerable<T>. First, you get one query language for any type of data, be it relational, XML, in-memory collections, etc. Second, that query language is not only going to be full of IntelliCrack goodness., but it will be checked for you at compile time, eliminating the need for nasty errors that crop up at runtime when SQL Server decides you don’t know anything about how to write SQL queries. Third, there’s a very short migration path from SQL (Unless you’re using VB 9, at which point there’s almost no migration path) or XQuery, so it’s not that hard to learn the new keywords and syntax.
Maybe someone from the other side of this argument would like to explain to my why they think these new features are unreadable, too complex, or why you wouldn’t use query capabilities built into the language. And, by the way, if you think that C# is too complex because it’s got these things in it, where are you going to go? Because VB 9 is going to have them as well.