从C# 3.0说以人为本(一)—— 编译器的支持
“科技,以人为本”,这句话是不是NOKIA自创的小凡不得而知,不过,在这方面做的最好的微软实在是要在里面占上一个很有力的位置。
且不说微软的操作系统进步有目共睹(当然也有如VISTA一般敢于吃螃蟹却因为华而不实遭到放弃的实例),事实上,在.NET项目中,对于C#语言和一些编程风格上的改进的确让小凡觉得处处都是为人着想。
说到.NET 3.0,最大的变化当属LINQ和Lambda表达式,我们先从LINQ入手,看看为了实现LINQ的功能,分析微软做了多少工作。
- class IntroToLINQ
- {
- static void Main()
- {
- // The Three Parts of a LINQ Query:
- // 1. Data source.
- int[] numbers = new int[7] { 0, 1, 2, 3, 4, 5, 6 };
- // 2. Query creation.
- // numQuery is an IEnumerable<int>
- var numQuery =
- from num in numbers
- where (num % 2) == 0
- select num;
- // 3. Query execution.
- foreach (int num in numQuery)
- {
- Console.Write("{0,1} ", num);
- }
- }
- }
上面一段代码是从MSDN原封不动抄下来的,熟悉C# 2.0的朋友对实例化一个int类型的数组和foreach自然不会陌生,但是,中间那看似SQL,又是写在C#中,并且是强类型(Strong Typed)的语句显得有点摸不着头脑。
首先,我们不得不说这样的语句非常方便,一目了然,就是取出数组中是偶数的数字并且单独形成一个IEnumerable<int>类型的序列。事实上,这个语句是可以翻译成最经典的C# 2.0方法的,我们从2.0慢慢一步步进化。如下:
二,最原始的2.0版本
- List<int> numQuery = new List<int>();
- foreach (int num in numbers)
- {
- if (num % 2 == 0)
- {
- numQuery.Add(num);
- }
- }
这个看起来是不是舒服了很多?非常标准的2.0代码哟。然而,3.0中加入了“扩展函数”和Lambda表达式这个概念,所以,这段2.0代码可以变成标准的3.0代码。
- IEnumerable<int> numQuery = numbers.Where((number) => number % 2 == 0);
突然觉得好简单!只要一行代码就完成了上面的工作!
等等,这个Where函数是哪儿来的?后面不知所云的((number) => number % 2 == 0)形参又是什么?这个我们放到后面再讨论。今天我们只关注编译器的支持。
经过两个版本的演变,我们可以看一下,到底哪个最好?事实上,如果熟悉C# 3.0,应该是最后一个版本最简洁方便。可是如果是刚入门的.NET程序员,看到最后一个版本的代码的时候,会不会扭头就走掉?这个代码有点晦涩,但是又有点方便,一时完全不知道怎么表达对这种语句的敬畏(事实上小凡一开始的确是这样的感受,可能是人笨没办法,呵呵)。
但是如果看第一个MSDN的示例,我想只要做过一点程序和数据库打过一点交道的人,都会知道这是什么意思。
事实上,
from num in numbers,不就是foreach (int num in numbers)吗?
where (num % 2) == 0,不就是if (num % 2 == 0)或者numbers.Where((number) => number % 2 == 0)吗?
select num,不就是numQuery.Add(num)吗?
通过编译器的支持,将面向对象的语句就可以变成灵活的LINQ语句,让大家既能减少代码的编写,也能更清楚的描述出代码所要做的意图,这是编译器上为了以人为本所做的工作。