1、 文档编号 版本 密级 1.0 本部门开放 工作规 共 15 页 软件开发代码规(C#版)拟制:日期:2007-2-13 审核:日期:审核:日期:批准:日期:所有*修订纪录 日期 修订版本 描述 作者 2007-2-13 1.00 初稿完成 2007-5-10 1.01 修正 2007-11-2 1.02 修正 目 录 1、第一章 命名规.4 1.1、第一节 总则.4 1.2、第二节 变量命名规.4 1.2.1、CodeBehind 部命名规.4 1.2.2、控件命名规.5 1.3、第三节 常量命名规.5 1.4、第四节 命名空间、类、方法命名规.5 1.5、第五节 接口命名规.6 1.6、第
2、六节 命名规小结.6 2、第二章 代码注释规.6 2.1、第一节 模块级注释规(命名空间、类等).6 2.2、第二节 方法级注释规.7 2.2.1、属性注释.7 2.2.2、方法注释.7 2.3、第三节 代码间注释规.8 3、第三章 编写规.9 3.1、第一节 格式规.9 3.2、第二节 编程规.9 3.2.1、程序结构要求.9 3.2.2、可读性要求.10 3.2.3、结构化要求.10 3.2.4、正确性与容错性要求.10 3.2.5、可重用性要求.11 3.2.6、interface 使用注意事项.11 3.2.7、类使用注意事项.11 3.2.8、流程控制语句注意事项.12 3.2.8、
3、其他应注意事项.13 注:Pascal命名法则:即名称中所有单词的第一个字母大写其他字母使用小写形式。Camel 命名法则:即名称中第一个单词各个字母全部小写,其他部分遵循 Pascal命名法则。1、第一章 命名规 1.1、第一节 总则 1 本命名规则除特殊提及外统一使用 Camel 命名法则。如:controlMenu 2 命名时尽量不使用拼音,更不可使用拼音缩写(专有名词除外)。3 如果使用品牌名称命名时其大小写尽量保持和品牌名称一致的样式。如:LuX 则命名时,不要写成 LUX,或者 Lux,而应该保持与原品牌名称风格一致使用 LuX 4 使用专有名词或英文缩写命名时采用大写形式。如:C
4、NNIC 5 禁止使用仅区分大小写的方式命名。如:Abc 与 abc仅用大写 A 来区分,这样写在类 C 系语言中不会出错,但是不利于系统的迁移 1.2、第二节 变量命名规 1.2.1、CodeBehind 部命名规 1公有字段/属性使用 Pascal 命名规则,私有变量/保护变量/局部变量使用 Camel 命名规则,遵循动宾结构。例:public class Hello private string userName;private DateTime loginTime;private bool isOnline;public string UserName get return this.
5、userName;2 即使对于可能仅出现在几个代码行中的生存期很短的变量,仍然使用意义描述性的名称。仅对于短循环索引使用单字母变量名,如 i 或 j 3在变量名中使用互补对,如 Min/Max、Begin/End 和 Open/Close。4当一个方法部变量繁多的时候,可以使用 Camel 命名法则,其中第一个单词可以使用变量类型的缩写来说明以示区别。例:string str Name;int int Age;object objPerson;1.2.2、控件命名规 1控件命名使用控件缩写加名称的方式 例:控件 缩写 声明 Label lbl protected Label lblName;T
6、extBox txt protected TextBox txtContent;CheckBox chk protected CheckBox chkRight;Button btn protected Button btnOK;ListBox lbx protected ListBox lstItem;DropDownList ddl protected DropDownList ddlArea;etc.1.3、第三节 常量命名规 常量名也应当有一定的意义,格式为 NOUN 或 NOUN_VERB。常量名均为大写,字之间用下划线分隔。例:private const bool WEB_ENAB
7、LEPAGECACHE_DEFAULT =true;private const int WEB_PAGECACHEEXPIRESINSECONDS_DEFAULT =3600;private const bool WEB_ENABLESSL_DEFAULT =false;注:变量名和常量名最多可以包含 255 个字符,但是,超过 25 到 30 个字符的名称比较笨拙。此外,要想取一个有实际意义的名称,清楚地表达变量或常量的用途,25 或 30 个字符应当足够了。1.4、第四节 命名空间、类、方法命名规 1名字应该能够标识事物的特性。2名字尽量不使用缩写,除非它是众所周知的。3名字可以有两个或三
8、个单词组成,但通常不应多于三个。4使用名词或名词短语命名类。5尽可能少用缩写。6不要使用下划线字符(_)。7命名空间名称使用此格式:Snda+项目名称+逻辑层名称 例:namespace Snda.CodeTest.BR public class FileStream public void InPut(string para)1.5、第五节 接口命名规 和类命名规相同,唯一区别是接口在名字前加上大写“I”前缀 例:interface IDBCommand;interface IButton;1.6、第六节 命名规小结 1、使用 Pascal 命名方式命名类、方法、属性和常量 2、使用 Cam
9、el 命名方式命名局部变量和方法的参数 3、接口使用 Pascal 命名方式,并且在前面添加“I”4、方法命名使用动宾结构,比如 ShowDialog()5、有返回值的方法命名应有单词来描述,比如 GetObjectState()6、避免使用带命名空间的类型,尽量用 using关键字 7、避免把 using语句放到命名空间 8、控件命名使用控件缩写加名称的方式 9、常量命名采用全部大写的形式,要想一个有实际意义的名称,清楚地表达常量的用途 2、第二章 代码注释规 2.1、第一节 模块级注释规(命名空间、类等)模块须以以下形式书写模块注释:/(功能模块简述)/名 称:(或者编号,当模块繁多的时候
10、以编号检索)/功 能:/程序设计:/开发日期:/备 注:/修 改 人:/修改日期:/备 注:(如果多次修改,请重复以上三项)/public class TestSpace 注意:详细说明都写在 部,为的是既方便 IDE 动态帮助又方便自动化出工程文档,适用以下注释规,不再赘述。修改人和修改日期每次修改的时候都要自行添加上去。2.2、第二节 方法级注释规 2.2.1、属性注释 属性必须以以下形式给予注释,如果有备注的需求请加在 部:/简述属性功能/备注/public string Name;2.2.2、方法注释/(简述方法功能)/param name=/对方法返回值的说明,该说明必须明确说明返回
11、的值代表什么含义/(使用示例)/名 称:(或者编号,当模块繁多的时候以编号检索)/功 能:/程序设计:/开发日期:/备 注:/修 改 人:/修改日期:/备 注:(如果多次修改,请重复以上三项)/public void TestMethod(string Para)2.3、第三节 代码间注释规 代码间注释分为单行注释和多行注释:单行注释:/多行注释:/*多行注释 1 多行注释 2 多行注释 3*/代码中遇到语句块时必须添加注释(if,for,foreach,),添加的注释必须能够说明此语句块的作用和实现手段(所用算法等等)。但是显而易见的代码不易注释。行间的注释量不得大于代码量的,不小于 2.4
12、、第四节 功能变更注释规 当对某个现有的功能进行修改时,需要在该功能所在的方法部加上注释,阐明变更容、变更时间、变更人。假如这一功能变更非常重要,请在模块描述中也加上相关注释。建议格式如下:/功能变更:XXXXX updated by who YYMMDD 3、第三章 编写规 3.1、第一节 格式规 1 所有的缩进为 1 个 Tab(设置 1 个 Tab 占 4 个空格空间),使用 VS.NET 的默认设置。2 在代码中垂直对齐左括号和右括号。例:if (x=0)this.Response.Write(用户编号必须输入!);允许以下情况:if (x=0)this.Response.Write(
13、用户编号必须输入!);不允许以下情况:if (x=0)this.Response.Write(用户编号必须输入!);3 为了防止在阅读代码时不得不滚动源代码编辑器,每行代码或注释在 1024*800 的显示频率下不得超过一显示屏。4 当一行被分为几行时,通过将串联运算符放在每一行的末尾而不是开头,清楚地表示没有后面的行是不完整的。5 每一行上放置的语句避免超过一条。6 在大多数运算符之前和之后使用空格,这样做时不会改变代码的意图却可以使代码容易阅读。例:int j=i+k;而不应写为 int j=i+k;7 将大的复杂代码节分为较小的、易于理解的模块。3.2、第二节 编程规 3.2.1、程序结
14、构要求 1 程序结构清晰,简单易懂,单个函数的程序行数不得超过 100 行。2 打算干什么,要简单,直截了当,代码精简,避免垃圾程序。3 尽量使用.NET 库函数和公共函数(无特殊情况不要使用外部方法调用 Windows 的核心动态库 API)。4 不要随意定义全局变量,尽量使用局部变量。3.2.2、可读性要求 1 保持注释与代码完全一致。2 去除无效的注释 3 处理过程的每个阶段都有相关注释说明。4 利用缩进来显示程序的逻辑结构,缩进量一致并以 Tab 键为单位,定义 Tab 为 4 个空格。5 循环、分支层次不要超过五层。6 注释可以与语句在同一行,也可以在上行,视语句的长短而定。7 一目
15、了然的语句不加注释。8 注释的作用围可以为:定义、引用、条件分支以及一段代码。9 去除 IDE 自动生成的注释,比如:.private void Page_Load(object sender,EventArgs e)/to do.(删除这段注释)3.2.3、结构化要求 1 禁止出现两条等价的支路。2 除了在 switch关键字的作用域,禁止 goto语句。3 用 if 语句来强调只执行两组语句中的一组。禁止 else goto 和 else return。4 用 case实现多路分支。5 避免从循环引出多个出口。6 函数只有一个出口。7 尽量不使用条件赋值语句。8 避免不必要的分支。9 不要
16、轻易用条件分支去替换逻辑表达式。3.2.4、正确性与容错性要求 1 程序首先是正确,其次是优美。2 无法证明你的程序没有错误,因此在编写完一段程序后,应先回头检查。3 改一个错误时可能产生新的错误,因此在修改前首先考虑对其它程序的影响。4 所有变量在调用前必须被初始化。5 对所有的用户输入,必须进行合法性检查。6 尽量不要比较浮点数的相等,如:10.0*0.1=1.0,不可靠,因为不同 CPU 的浮点运算能力是不同的 7 程序与环境或状态发生关系时,必须主动去处理发生的意外事件,如文件能否逻辑锁定、打印机是否联机等,对于明确的错误,要有明确的容错代码提示用户,在这样不确定的场合都使用 try
17、throw catch。8 单元测试也是编程的一部份,提交联调测试的程序必须通过单元测试。9 尽量使用规的容错语句.例:try catch finally 3.2.5、可重用性要求 1 重复使用的完成相对独立功能的算法或代码应抽象为 服务或类。2 服务或类应考虑 OO 思想,减少外界联系,考虑独立性或封装性。3.2.6、interface 使用注意事项 1避免一个接口中只有一个成员。尽量使每个接口中包含 35 个成员。接口中的成员不应该超过 20 个。避免接口成员中包含事件。2推荐使用显式的接口实现。3.2.7、类使用注意事项 1避免方法的返回值是错误代码。2尽量定义自定义异常类。当需要定义自
18、定义的异常时:a)自定义异常要继承于 ApplicationException。b)提供自定义的序列化功能。3只对外公布必要的操作。4使程序集尽量为最小化代码(EXE 客户程序)。使用类库来替换包含的商务逻辑。5不要提供 public的成员变量,使用属性代替他们。6避免在继承中使用 new 而使用 override替换。7在不是 sealed的类中总是将 public 和 protected的方法标记成 virtual 的。8避免显式的转换,使用 as 操作符进行兼容类型的转换。例:Dog dog=new GermanShepherd();GermanShepherd shepherd=dog
19、 as GermanShepherd;if (shepherd!=null )9当类成员包括委托的时候在调用委托之前一定要检查它是否为 null 例:public class MySource public event EventHandler MyEvent;public void FireEvent()EventHandler temp=MyEvent;if(temp!=null )temp(this,EventArgs.Empty);10不要提供公共的事件成员变量,使用事件访问器替换这些变量。例:public class MySource MyDelegate m_SomeEvent;p
20、ublic event MyDelegate SomeEvent add m_SomeEvent+=value;remove m_SomeEvent-=value;11避免在结构里面提供方法。建议使用参数化构造函数,可以重裁操作符。12类成员间调用请尽量使用 this 关键字。13除非你想重写子类中存在名称冲突的成员或者调用基类的构造函数否则不要使用base 来访问基类的成员。3.2.8、流程控制语句注意事项 1即使 if 语句只有一句,也要将 if 语句的容用大括号扩起来。2 避免在条件语句中调用返回 bool值的函数。可以使用局部变量并检查这些局部变量。例:bool IsEverythin
21、gOK()/避免 if (IsEverythingOK()/替换方案 bool ok=IsEverythingOK();if (ok)3总是使用基于零开始的数组。4在循环中总是显式的初始化引用类型的数组。例:public class MyClass MyClass array=new MyClass100;for(int index=0;index array.Length;index+)arrayindex=new MyClass();5除非在不完全的 switch语句中否则不要使用 goto 语句。3.2.8、其他应注意事项 1避免将多个类放在一个文件里面。2一个文件应该只有一个命名空间,
22、避免将多个命名空间放在同一个文件里面。3一个文件最好不要超过 500 行的代码(不包括机器产生的代码)。4避免方法中有超过 5 个参数的情况。使用结构来传递多个参数。5每行代码不要超过 80 个字符。6不要手工的修改机器产生的代码。如果需要编辑机器产生的代码,编辑格式和风格要符合该编码标准。7不要硬编码数字的值,总是使用构造函数设定其值或采用常数的方式。8只有是自然结构才能直接使用 const,比如一个星期的天数。9避免在只读的变量上使用 const。如果想实现只读,可以直接使用 readonly。例:public class MyClass public readonly int Numbe
23、r;public MyClass(int someValue)Number=someValue;public const int DAYS_IN_WEEK=7;10代码的每一行都应该通过白盒方式的测试。11在捕获(catch)语句的抛出异常子句中(throw),总是抛出原始异常维护原始错误的堆栈分配。例:catch(Exception exception)MessageBox.Show(exception.Message);throw;/和 throw exception一样。12避免在单个程序集里使用多个 Main 方法。13数据访问中凡是使用 DateReader 对象的,必须使用 usi
24、ng语句来即时释放资源;对于 Stream、StreamReader 之类的对象,也要使用 using语句来即时释放资源 14避免指定特殊类型的枚举变量。例:/避免 public enum Color :long Red,Green,Blue 15不要硬编码可能更改的基于配置的字符串,比如连接字符串。16当需要构建长的字符串的时候,使用 StringBuilder 不要使用 string 17能使用早期绑定就不要使用后期绑定。18使用应用程序的日志和跟踪。19总是选择使用 C#置(一般的 generics)的数据结构。比如:使用 int 而不用 Int32,使用 object 而不用 Obje
25、ct,使用 string 而不用 String 等。20将所有的系统命名空间组织在一起,将所有自定义的命名空间组织在一起 例:using System;using System.Data;using System.Collections;using MyNameSpace;using MyControls;21数据访问方法编写完成之后,必须进行单元测试,保证调用无异常。22使用一个对象(或对象的属性)前,必须保证该对象非空(作 null 判断)。23使用一个数组中的某个元素时,必须保证不会超出索引界限。24A开发中,对于 Repeater、DataList、GridView一类的服务器控件。应
26、本着节约服务器资源的原则,能用 DataList 完成的就不用 GridView,能用 Repeater完成的就不用 DataList。25A 开发中,对于页面上服务器端控件产生的 ViewState,没实际用处的就直接禁用;对于首页、频道页等会被缓存的页面,要慎重使用服务器端控件,不允许产生任何 ViewState,并且不要使用 postback提交 26A 开发中,对于页面上服务器端控件产生的 ViewState,没实际用处的就直接禁用;对于首页、频道页等会被缓存的页面,要慎重使用服务器端控件,不要使用postback提交,不允许产生任何 ViewState 27对于数据访问层、业务层和页面层抛出的异常,要区分出 Exception和 Error,对这两种情况进行区分处理。Exception一般指数据库的、非控的严重错误,务必要记录下异常类型以及堆栈信息,以便将来排查问题;对于 Error通常都是指业务错误,此时需要记录下发生错误的相关参数和 errorcode以便重现问题即可。28 WEB页面开发完成后,要作浏览器兼容性测试(IE6、FF 最新版、google浏览器)28 下班前要确保工程里的所有文件处于签入状态(对于已经开发完成并测试通过的功能可以直接签入;对于尚未开发完成或者尚未经 QA确认的功能则先注释掉相关修改,再行签入)