代码风格的避免代码过于拥挤

如题所述

第1个回答  2016-05-28

想想人们为什么喜欢为文章添加各级标题以及其他复杂的格式,是因为美观吗?也许是的,但我相信这些格式可以更容易地让人们理清思路。可是在程序中,我们无法使用这些手段,所有的代码都是纯文本的,即使Visual Studio的代码高亮功能可以为代码的不同部分标上不同的颜色,但这并不能真正影响到代码本身。因此,光是换行还是不够的,我们还需要更多的手段。 适当地添加空行则是一个非常有效的代码整理方式——有点像文章中的分段,一段意思也许需要若干个句子才能表达清楚,在表达下一段意思之前,应当另起一段。
首先,每个C# 代码文件是从命名空间引用开始的,一组引用结束之后,则是命名空间的声明及类型的声明。很显然地,在命名空间引用与命名空间声明之间,应该留有一个空行以示区隔:
代码示例1-8:在命名空间引用之后添加空行
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Text;
using Avilla.Metadata;
using Avilla.Searching;
// 这里用空行隔开
namespace Avilla
{
// 下面的内容省略
一个空行,意味着不同的功能块的分隔,如果读者稍加留心,就会发现Visual Studio自动生成的代码,总是在类型的各个成员之间留有一个空行。我们在书写代码的时候,也可以模仿这一格式:
代码示例1-9:在类型的各个成员之间添加空行
/// <summary>
/// 表示一条搜索条件的抽象基类
/// </summary>
public abstract class SearchCondition
{
/// <summary>
/// 初始化一个 <see cref=SearchCondition/> 类型的实例,并指明是否区分大小写
/// </summary>
/// <param name=caseSensitive>是否区分大小写</param>
protected SearchCondition(bool caseSensitive)
{
this.caseSensitive = caseSensitive;
}
// 这里用空行隔开
protected bool caseSensitive = false;
/// <summary>
/// 获取或设置一个 <see cref=Boolean/> 类型的值,以指示是否区分大小写
/// </summary>
public bool CaseSensitive
{
get { return caseSensitive; }
set { caseSensitive = value; }
}
// 这里用空行隔开
/// <summary>
/// 获取表示此搜索条件的 SQL 筛选条件表达式
/// </summary>
/// <returns>
/// 返回一个字符串形式的条件表达式,可直接用于 SQL 语言中的 WHERE 子句
/// </returns>
public abstract string GetFilterExpression();
}
}
这样排版无疑会使得每个成员的代码段更富独立性,绝大多数的编译器,在自动生成代码时都会遵照此方式排版。您可能会发现,上例中的caseSensitive字段与CaseSensitive属性之间并未留有空行,这是为了强调字段与其对应用于公开访问的属性之间的联系,关于类似情况,我们将在后面的章节详细讨论。
然而,一个空行意味着的不仅仅是功能模块的界限,它更是对代码逻辑块的划分。我们无法期望每个操作都只通过一行代码一条语句来完成,大多数情况下,它们都需要许多行代码来执行一个完整的操作。例如,你想查询数据库,那么你需要先生成SQL代码,建立命令,然后执行这个命令并填充至数据集。这中间大约需要使用四五行代码,而这四五行代码便组成了一个相对紧密的逻辑块,它与其后面的其他逻辑块即可以通过一个空行来进行分隔。请看下面的一个例子:
代码示例1-10:用空行分隔逻辑块
public static string[] GetPhotoIds(string filterExpression, string sort, bool caseSensitive)
{
// 第一个逻辑段代码根据处理后的参数取得数据行
xml.Photos.CaseSensitive = caseSensitive;
DataRow[] rows =
xml.Photos.Select(filterExpression, sort ?? string.Empty);
// 遍历数据行,取出需要的元素
string[] ids = new string[rows.Length];
for (int i = 0; i < rows.Length; i++)
{
ids = (string)rows[Id];
}
// 返回结果
return ids;
}
这个函数的目的是根据指定的筛选条件和排序规则返回照片的标识号(Photo IDs),函数内部自然形成了三个逻辑段:先是根据要求取得原始数据,然后从原始数据中提取我们需要的部分,最后将结果返回。用空行将这三个逻辑区分隔开来将会更加有利于我们理解其思路。关于注释的合理使用,我们会在后面的章节中再专门介绍。
既然空行可以起到分隔代码,提高清晰度的作用,那么有的朋友也许会为了强调这种分隔效果,多加几个空行。可事实的效果是,连续的多个空行,在并未提高多少清晰度的同时,浪费了屏幕的空间,而且会让人觉得前后两个代码段并不相关——事实上它们应该是相继执行的。空行的意义和文章的段落一样,仅在于表示一个停顿,而并非结束。 Basic、Pascal与C这三种早期高级程序设计语言的语法,至今仍在发挥着其重要的作用。Visual Basic仍然保留着Basic的句法简单、多用完整英文单词、贴
近自然语序的习惯(如And、Not、Inherits、Implements、Handles等等关键字);而Delphi更是延续着Pascal语言那标志性的BEGIN-END作风。C语言由于在
操作系统开发上取得了成功,使得它在软件开发历史上占据了绝对的优势,相比而言,它的语法更加具有影响力,广泛被C++、Java、C#,乃至用于编写网页
的ECMAScript/JavaScript和Flash的脚本语言ActionScript所吸纳,因此也变化丰富。但是它那种善用符号的古老特色一直被保留了下来,有理由相信,C语
言是使用符号最多的语言。当其他语法体系都采用AND、OR等关键字作为运算符时,C语言却使用了“&&”、“||”这样的符号,虽然在语法上并没有增加任
何复杂性,但各种奇形怪状难以记忆的符号还是会令初学者望而却步。让我们来比较一下下面的几行代码:
BASIC: If a>b And c<>d Or Not e>f Then ...
PASCAL: If (a>b) And (c<>d) Or (Not (e>f)) Then ...
C: if(a>b&&c!=d||!(e>f)) ...
这三行的意义是完全相同的,但明显可以让人感觉到清晰程度的差异,Basic和Pascal的代码看上去很容易明白,而C语言的代码却像蚂蚁一般缩成一团。
重要的原因在于:C语言的运算符几乎都只由“符号”构成,与变量名之间不需要用空格充当分隔符。这样一来,由于缺少空格的稀释,C语言的代码就像被浓缩过似
的——现如今它除了影响我们阅读以外,没有什么好处。因此我们有必要人为地添加一点空格,帮它降低代码的“密度”。这里,我总结了一些关于如何在运算

相似回答