为什么要规范编码?
方便维护、便于阅读和理解代码。
注释
所有的方法和函数都应该在前面添加注释,表明方法用来干什么。
当参数的功能不明显时、过程希望参数在一个特定的范围内时 ,也要注释说明该参数的作用
模块头部注释规范
在每一个物理文件为单元的头部,都需要有模块头部注释。
方法注释规范
- 具体应用中,类、接口、属性、方法必须有节,另外方法如果有参数及返回值,则必须有及节。
/// <summary> /// ...方法(翻译) /// </summary> /// <param name="参数名"></param> /// <returns>返回值</returns>
-
事件不需要头注解,但包含复杂处理时(如:循环/数据库操作/复杂逻辑等),应分割成单一处 理函数,事件再调用函数。
-
所有的方法必须在其定义前增加方法注释。方法注释采用 /// 形式自动产生XML标签格式的注释。
-
在公用类库中的公用方法需要在一般方法的注释后添加作者、日期及修改记录信息。
统一采用XML标签的格式加注,标签如下:
<Author>作者</Author> <CreateDate>建立日期</CreateDate> <RevisionHistory> --修改记录 <ModifyBy>修改作者</ModifyBy> <ModifyDate>修改日期</ModifyDate> <ModifyReason>修改理由</ModifyReason> <ModifyBy>修改作者</ModifyBy> <ModifyDate>修改日期</ModifyDate> <ModifyReason>修改理由</ModifyReason> <ModifyBy>修改作者</ModifyBy> <ModifyDate>修改日期</ModifyDate> <ModifyReason>修改理由</ModifyReason> </RevisionHistory> <LastModifyDate>最后修改日期</LastModifyDate
-
一个代码文件如果只有一个人编写,则无需添加作者信息。非代码文件作者在此文件添加方法时,必须要添加作者、日期等注释。
-
修改任何方法,必须要添加修改记录的注释。
行代码注释规范
-
处理某一个功能需要很多行代码实现,并且有很多逻辑结构块,则需要在此行代码前注释,说明此块代码的处理思路及注意事项等
-
注释从新行增加,与代码开始处左对齐
-
双斜线与注释之间以空格分开
变量注释规范
-
定义变量时需添加变量注释,用以说明变量的用途。
-
Class级变量(含static)应以采用 /// 形式自动产生XML标签格式的注释(三行)
-
方法级的变量(方法里面的)注释可以放在变量声明语句的后面,与前后行变量声明的注释左对齐,注释与代码间以Tab隔开。
命名
命名的基本约定
-
使用可以准确说明变量/字段/类的完整的英文描述符,如firstName 。对一些作用显而易见的变量,采用简单的命名,如循环里的递增(减)变量就可以被命名为 “i”
-
要采用大小写混合,提高名字的可读性。不采用下划线作分隔字符的写法
有两种适合的书写方法,适应于不同类型的标识符:(1)PasalCasing :标识符的第一个单词的字母大写; (2)camelCasing :标识符的第一个单词的字母小写。
-
不同类型标识符的大小写规则:
总结:私有字段、参数、局部变量:使用驼峰命名。
-
对常见缩略词,两个字母的缩写要采用统一大小写的方式(示例:ioStream,getIOStream);多字母缩写采用首字母大写,其他字母小写的方式(示例:getHtmlTag);
-
避免使用长名字(15个字母)、避免使用相似或仅有大小写区分的名字。
各种标识符类型的命名约定
-
程序集命名 XLN.Comlib.
实验室名称(Lab)+ 项目名称 + 模块名称(可选),例如: XLN.ComLib.DB ;中心服务器程序集:Lab.SeverCenter;中心服务器业务逻辑程序集:Lab.SeverCenter.Business;
-
命名空间命名 采用和程序集命名相同的方式
实验室名称(Lab)+ 项目名称 + 模块名称。 另外,一般情况下建议命名空间和目录结构相同。例如:
中心服务器:Lab.SeverCenter;
中心服务器下的用户控件:Lab.SeverCenter.UserControl;中心服务器业务逻辑:Lab.SeverCenter.Business; -
程序集和DLL
大多数情况下,程序集包含全部或部分可重用库,且它包含在单个动态链接库(DLL) 中。
例:Lab.SeverCenter.dll
-
类和接口命名
类的名字要用名词;避免使用单词的缩写
接口的名字要以字母I开头。保证对接口的标准实现名字只相差一个“I”前缀,例如对IComponent 接口的标准实现为Component;
泛型类型参数的命名:命名要为T或者以T开头的描述性名字
对同一项目的不同命名空间中的类,命名避免重复。避免引用时的冲突和混淆。
-
方法命名
第一个单词一般是动词
如果方法返回一个成员变量的值,方法名一般为Get+成员变量名;
如若返回的值是bool变量,一般以Is作为前缀。
如果方法修改一个成员变量的值,方法名一般为:Set + 成员变量名。
-
变量命名
变量的命名规则基本相同,见标识符大小写对照表。区别如下:
a) 类的公有变量按通常的方式命名,无特殊要求;
b) 类的私有变量采用两种方式均可:采用加“m”前缀,例如mWorkerName;
c) 方法的参数变量采用camalString,例如workerName; d) 方法内部的局部变量采用camalString,例如workerName。
e) 不要用_或&作为第一个字母; f) 尽量要使用短而且具有意义的单词;
g) 单字符的变量名一般只用于生命期非常短暂的变量:i,j,k,m,n一般用于integer;c,d,e 一般用于characters;s用于string
h) 如果变量是集合,则变量名要用复数。例如表格的行数,命名应为:RowsCount;
i) 命名组件要采用匈牙利命名法,所有前缀均应遵循同一个组件名称缩写列表
控件名称缩写列表
缩写的基本原则是取组件类名各单词的第一个字母,如果只有一个单词,则去掉其中的元音,留下 辅音。缩写全部为小写。
其它规范
编码风格
变量声明
为了保持更好的阅读习惯,请不要把多个变量声明写在一行中,即一行只声明一个变量。
代码缩进
代码缩进使用Tab键实现,最好不要使用空格,为保证在不同机器上使代码缩进保持一致,特此规 定C#的Tab键宽度为4个字符
避免方法中有超过5个参数的情况,一般以2,3个为宜。如果超过了,则应使用struct来传递多个参数。 方法参数多于8个时采用结构体或类方式传递
程序中不应使用goto语句。 在switch语句中总是要default子句来显示信息
操作符/运算符左右空一个半角空格
所有块的{}号分别放置一行,并嵌套对齐,不要放在同一行上
空白
- 下列情况应该总是使用两个空行: a) 一个源文件的两个片段(section)之间。 b) 类声明和接口声明之间。
- 下列情况应该总是使用一个空行: a) 两个方法之间。 b) 方法内的局部变量和方法的第一条语句之间。 c) 块注释或单行注释之前。 d) 一个方法内的两个逻辑段之间,用以提高可读性。
- 下列情况应该总是使用空格: a) 空白应该位于参数列表中逗号的后面,如: void UpdateData(int a, int b) b) 所有的二元运算符,除了".",应该使用空格将之与操作数分开。一元操作符和操作数之间不应该加空格,比如:负号("-")、自增("++")和自减("--")。例如: a += c + d; d++; c) for 语句中的表达式应该被空格分开,例如: for (expr1; expr2; expr3) d) 强制转型后应该跟一个空格,例如: char c; int a = 1; c = (char) a;
资源释放
所有外部资源都必须显式释放。例如:数据库连接对象、IO对象等。
错误处理
- 不要“捕捉了异常却什么也不做“。
- 发生异常时,给出友好的消息给用户,但要精确记录错误的所有可能细节,包括发生的时间, 和相关方法,类名等。
- 只捕捉特定的异常,而不是一般的异常。
其它
- 一个方法只完成一个任务
- 使用C#的特有类型,而不是System命名空间中定义的别名类型
- 别在程序中使用固定数值,用常量代替
- 避免使用很多成员变量。声明局部变量,并传递给方法。不要在方法间共享成员变量。如果在 几个方法间共享一个成员变量,那就很难知道是哪个方法在什么时候修改了它的值。
- 别把成员变量声明为 public 或 protected。都声明为 private 而使用 public/protected 的属性
- 不在代码中使用具体的路径和驱动器名。 使用相对路径,并使路径可编程。
- 应用程序启动时作些“自检”并确保所需文件和附件在指定的位置。必要时检查数据库连接。出现 任何问题给用户一个友好的提示。
- 如果需要的配置文件找不到,应用程序需能自己创建使用默认值的一份。
- 如果在配置文件中发现错误值,应用程序要抛出错误,给出提示消息告诉用户正确值。
- DataColumn取其列时要用字段名,不要用索引号。 例: 正确DataColumn[“Name”] 不好 DataColumn[0]
- 在一个类中,字段定义全部统一放在class的头部、所有方法或属性的前面。
- 在一个类中,所有的属性全部定义在一个属性块中: