不过如果这里我们使用DSL,也就是LINQ,就像这样:
var result = products
.Where(p => p.UnitPrice >= 20)
.GroupBy(p => p.CategoryName)
.OrderByDescending(g => g.Count())
.Select(g => new { CategoryName = g.Key, ProductCount = g.Count() });products
.Where(p => p.UnitPrice >= 20)
.GroupBy(p => p.CategoryName)
.OrderByDescending(g => g.Count())
.Select(g => new { CategoryName = g.Key, ProductCount = g.Count() });products
……先调用Where……blablabla……再GroupBy等等。由于我们这里可以使用DSL来表示高阶的术语,用以体现我们想做的事情。于是这段代码则更加关注于“What”而不是“How”。我这里不会明确地指示我想要过滤的方式,我也不会明确地说我要建立字典和分类,这样基础结构就可以聪明地,或者说更加聪明地去确定具体的执行方式。你可能比较容易想到我们可以并行地执行这段代码,因为我没有显式地指定做事方式,我只是表示出我的意图。
我们打开页面……(打开页面)很显然我们得到了相同的结果。
var result =
from p in products
where p.UnitPrice >= 20
group p by p.CategoryName into g
orderby g.Count() descending
from p in products
where p.UnitPrice >= 20
group p by p.CategoryName into g
orderby g.Count() descending
这里比较有趣的是,内部DSL是如何设计进C#语法中的,为此我们为C# 3.0添加了一系列的特性,例如Lambda表达式,扩展方法,类型推断等等。这些特性统一起来之后,我们就可以设计出更为丰富的API,组合之后便成为一种内部DSL,就像这里的LINQ查询语言。
除了使用API的形式之外,我们还可以这样做:
select new { CategoryName = g.Key, ProductCount = g.Count() };
编译器会简单地将这种形式转化为前一种形式。不过,这里我认为有意思的地方在于,你完全可以创建一门和领域编程语言完全无关的语法,然后等这种语法和API变得流行且丰富起来之后,再来创一种新的表现形式,就如这里的LINQ查询语法。我颇为中意这种语言设计的交流方式。
OK,现在我们回到下面的内容。
(未完待续)