《Effective C#》读书笔记——条目8:推荐使用查询语法而不是循环<C#语言习惯>

简介:

 查询语法(query syntax)可以让程序逻辑的表达由“命令式”转换为“声明式”。查询语法定义了想要的结果,而把具体实现交给其他的专门实现。使用查询语法(实现了查询表达式模式的方法语法也可以)要比传统的命令式循环结果更加清晰的表达你的意图。

  下面我们观察一个使用命令式方法填充一个数组,然后将其内容输出至控制台:

复制代码
 1   static void Main(string[] args)
 2         {
 3             int[] foo = new int[100];
 4             for (int num = 0; num < foo.Length; num++)
 5             {
 6                 foo[num] = num * num;
 7             }
 8             foreach (int i in foo)
 9             {
10                 Console.WriteLine(i);
11             }
12             Console.Read();
13         }
复制代码

 

编写命令式的代码需要关注具体的实现细节。但是如果采用查询语法,实现同样的功能,代码更加易于重用且易读,我们来看上面示例“声明式”的写法:

复制代码
 1   static void Main(string[] args)
 2         {
 3             //生成数组的工作交个一个查询完成
 4             int[] foo = (from n in Enumerable.Range(0, 100) select n * n).ToArray();
 5 
 6             //循环打印的工作交给一个数组的扩展方法来完成
 7             foo.ForAll((n) => Console.WriteLine(n.ToString()));
 8 
 9             Console.Read();
10         }
复制代码

我们看到在负责循环打印部分我们使用了一个扩展方法,这个扩展方法带来了更好的重用性,每次需要对一个序列的元素执行某个操作都可以使用ForAll()方法:

复制代码
 1 public static class Extensions
 2 {
 3     /// <summary>
 4     /// 为IEnumerable<T>类型添加扩展方法
 5     /// </summary>
 6     /// <typeparam name="T"></typeparam>
 7     /// <param name="sequence"></param>
 8     /// <param name="action"></param>
 9     public static void ForAll<T>(this IEnumerable<T> sequence, Action<T> action)
10     {
11         foreach (T item in sequence)
12         {
13             action(item);
14         }
15     }
16 }
复制代码

 

上面的实例比较简单,似乎看不出二者有多大的区别,在下面的实例中我们分别使用“命令式”和“声明式”来实现比较二者的区别 。

命令式:

View Code

 

声明式:

View Code

 我们可以看到随着编程任务的复杂:

  “命令式”版本变得越来越难以理解。如果仔细看的话,甚至都不会发现比较函数中参数被颠倒了(这是个错误),而这只是为了能够降序排列而已。要是没有任何注释和稳定,命令式代码将会更加难以阅读。”命令式“代码太过于强调实现目标所需要的详细步骤,以至于让人很容易陷入具体的细节中。

  “声明式”版本的最后一个实现,实际只是将以此过滤(where子句)、以此排序(orderby子句)和一个投射(select)组合起来。查询语法比循环结构能够提供更具组合性的API。查询语法很自然的将算法分解成小块代码,每一块代码静对序列中的元素进行单一操作。查询语法的延迟执行模式也让开发者能够将这些单一的操作组合成多步的操作,且只要一次遍历序列就可以完整执行,而循环语法结构则必须为每一步操作都创建临时的存储,或者为序列将要执行的每一批操作都创建专用的方法。

 

小节:

当你需要编写循环时,首先看看能否用查询语法实现,若是无法使用查询语法,那么再看看是否能以方法调用语法替代。这样写出的代码总会比命令式循环结构要简洁一些。

本文转自gyzhao博客园博客,原文链接:http://www.cnblogs.com/IPrograming/archive/2012/09/01/Effective_CSharp_08.html ,如需转载请自行联系原作者
相关文章
|
7月前
|
存储 开发框架 .NET
【C#】C# 基础语法与游戏开发
【1月更文挑战第21天】【C#】C# 基础语法与游戏开发
C#的基本语法结构学习案例详解
C#的基本语法结构学习案例详解
63 0
|
7月前
|
C#
C#的基本语法结构学习
【5月更文挑战第17天】C#基础语法包括变量(如`int x = 10`)、常量(`const int MAX_VALUE = 100`)、运算符(如算术和比较运算符)、控制语句(if、for、while等)和函数声明(`int Add(int x, int y) { return x + y; }`)。这些构成C#程序的基本元素。
81 0
|
4月前
|
存储 C# 索引
C# 集合语法全解
C# 集合语法全解
35 0
|
7月前
|
开发框架 安全 .NET
C# .NET面试系列一:基础语法
<h2>基础语法 #### 1. 字符串中 string str = null 和 string str = "" 和 string str = string.Empty 的区别? string str=null: ```c# 这表示字符串变量str被初始化为null,即它不引用任何对象。这与空字符串是不同的,因为空字符串是一个具有零长度的字符串对象,不会分配内存空间 ``` string.Empty: ```c# 这表示字符串变量str被初始化为空字符串,即一个具有零长度的字符串对象。这与null是不同的,因为str引用了一个空字符串对象 ``` string str="" :
130 1
|
7月前
|
C#
C#语法快速热身
C#语法快速热身
|
7月前
|
存储 C# 开发者
C#基础语法
C#基础语法
36 0
|
7月前
|
存储 C#
C#基础语法(类和对象)
C#基础语法(类和对象)
44 2
|
7月前
|
存储 C#
C#基础语法(数组和函数)
C#基础语法(数组和函数)
68 1
|
7月前
|
C#
C#基础语法(判断和循环)
C#基础语法(判断和循环)
61 1