规则:编程时必须遵守的约定。
建议:编程时必须加以考虑的约定。
1 代码格式
【规则 1-1】全部代码使用TAB键缩进。
【规则 1-2】代码行的长度小于120个字符。
【规则 1-3】“{”放在行首,“}”新起一行也在行首。
【规则 1-4】不要在相关的一组类或者是一个模块中使用不同的代码格式。
【规则 1-5】成员按照一定的顺序,并且使用#region分组。
2 命名规范
【规则 2-1】使用英文命名标识符。
【规则 2-2】使用Pascal大小写和Camel大小写命名标识符。
l Pascal大小写是每个单词的首字母大写。例如:BackColor。
l Camel大小写是第一个单词的首字母小写,其余单词的首字母大写。例如:backColor。
【规则 2-3】不使用匈牙利命名法。
〖建议 2-1〗注意缩写的使用。
l 如果不是绝对必须,尽量避免使用短的名称。
l 如果标识符中单词的缩写只能缩短一两个字符则使用单词的完全拼写。
l 所有单词的缩写规则应当一致。
〖建议 2-2〗标识符应当直观且可以拼读,可望文知意,不必进行“解码”。
【规则 2-4】DLL Assembly命名使用它所包含的命名空间。
【规则 2-5】文件名和所包含的类名相同。
【规则 2-6】所有布尔型变量的命名能够直接从名称上看出为真的条件。
【规则 2-7】程序中不要出现仅靠大小写区分的相似的标识符。
3 注释
【规则 3-1】每个CS文件都包含文件头,并且使用#region分组。
【规则 3-2】文件头说明版权、文件名和文件的作者,创建时间,变更记录。
【规则 3-4】注释使用//,不使用//-----------------或者//************。
〖建议 3-1〗所有的注释都应该用英文或者中文,同一段注释不要混用两种语言。
【规则 3-5】使用XML标记说明类型和成员。
【规则 3-6】代码变更需要将旧代码注释,并且说明变更原因,变更作者和变更时间。
4 变量使用
〖建议 4-1〗在接近使用变量的地方定义和初始化变量。
〖建议 4-2〗如果可能,在定义的同时初始化变量。
【规则 4-1】一个定义语句只定义一个变量,以便于写注释。
〖建议 4-3〗设置引用为null告诉GC对象不再需要。
【规则 4-2】不使用“魔术数字”。
if (custTypeId == 1) //错误 int ORG_CUST_TYPE_ID = 1; if (custTypeId == ORG_CUST_TYPE_ID) //正确 |
【规则 4-3】使用StringBuilder或者String.Format构造字符串。
5 控制流
【规则 5-1】不要在for循环内部改变循环变量的值。
〖建议 5-1〗if、for、while、do等语句自占一行,执行语句不得紧跟其后。不论执行语句有多少都要加{}。这样可以防止书写失误。
〖建议 5-2〗在switch语句中总是要有default子句。建议使用断言。
int number = SomeMethod(); switch(number) { case 1: Trace.WriteLine("Case 1:"); break; case 2: Trace.WriteLine("Case 2:"); break; default : Debug.Assert(false); break; } |
6 异常
【规则 6-1】仅在例外情况下抛出异常。
【规则 6-1】仅在需要指定异常时re-throw异常。
【规则 6-1】使用<exception>标记显式的列出方法和属性可能抛出的异常。
【规则 6-1】在异常抛出时需要记录日志。
【规则 6-1】使用.NetFramework已经提供异常。
【规则 6-1】抛出附带信息的异常。
【规则 6-1】抛出最合适的异常。
【规则 6-1】只捕捉在文档显式说明的异常。
7 [C1] SQL编码规范
【规则 7-1】SQL语句全部大写。
【规则 7-2】连接符OR、IN、AND、以及=、<=、>=等前后加上一个空格。
【规则 7-3】对较为复杂的SQL语句加上注释,说明算法、功能。
【规则 7-4】WHERE子句的每个条件占一行,并且以保留字开始。
【规则 7-5】多表连接时,使用表的别名来引用列。
【规则 7-6】使用明确的列代替SELECT *。
SELECT A.ID, A.NAME, B.ID B_ID, B.NAME B_NAME FROM CLASS A, SCHOOL B WHERE A.SCHOOL_ID = B.ID AND A.STATE = ‘ AND B.STATE = ‘ |
8 附录
8.1 代码范例
#region Copyright Ztesoft 2004 // // All rights are reserved. Reproduction or transmission in whole or in part, in // any form or by any means, electronic, mechanical or otherwise, is prohibited // without the prior written consent of the copyright owner. // // Filename: PatientList.cs // Author: TangXing // CreateDate: // // Modified By TangXing // ChangedDate: // Reason: BugId=555 // #endregion using System; using System.Collections; namespace Ztesoft.BS.PatientList { /// <summary> /// Objects of this class manage a list of patients and their history. /// </summary> /// <remarks> /// This class relies on the <see cref="Patient"/> class. /// </remarks> /// <seealso cref="Patient"/> public class PatientList { /// <summary>Holds a list of Patient objects.</summary> private ArrayList list = new ArrayList(); /// <summary>Maximum number of patients supported.</summary> private const uint maxPatients = 100; /// <summary>Defines the gender of the patient.</summary> public enum Gender { /// <summary>The patient is a male.</summary> Male, /// <summary>The patient is a female.</summary> Female, /// <summary>A phantom object used for testing</summary> Phantom } /// <overloads> /// Adds new patients to the list. /// </overloads> /// <summary> /// Adds a new patient to the end of the current list. /// </summary> /// <remarks> /// The actual data of the Patient object is not checked or changed. /// </remarks> /// <exception cref="NullReferenceException"> /// The <paramref name="patient"/> argument was null. /// </exception> /// <param name="patient">The patient object to add.</param> /// <returns> /// <b>true</b> if the patient was added, </b>false</b> if the list is /// full. /// </returns> public bool Add(Patient patient) { if (null == patient) { throw new NullReferenceException( "patient argument must not be null"); } bool success = false; if (list.Count < maxPatients) { list.Add(patient); success = true; // Raise the event and pass the new patient to the event // handler. Added(this, new PatientAddedEventArgs(patient)); } return success; } /// <summary> /// Adds a new patient at the specified index in the list. /// </summary> /// <remarks> /// The following rules apply. /// <list type="bullet"> /// <item> /// The actual data of the Patient object is not checked or /// changed. /// </item> /// <item> /// The item at the specified <paramref name="index"/> will be /// moved one place up. /// </item> /// </list> /// </remarks> /// <exception cref="NullReferenceException"> /// The <paramref name="patient"/> argument was null. /// </exception> /// <exception cref="IndexOutOfBounds"> /// The index was invalid. /// </exception> /// <param name="patient">The patient object to add.</param> /// <param name="index">The index to use for inserting.</param> /// <returns> /// true if the patient was added, false if the list is full. /// </returns> public bool Add(Patient patient, int index) { // Code left out for brevity. } /// <summary> /// Searches the contents of the list for patients of a certain gender. /// </summary> /// <param name="gender">The gender to use during matching.</param> /// <returns> /// Returns an array of <see cref="Patient"/> objects or <b>null</b> if /// no items have been found. /// </returns> public Patient[] GetPatientsByGender(Gender gender) { // Code left out for brevity. } /// <summary> /// Gets a value indicating the size of the list. /// </summary> /// <value> /// The current number of entries in the list. /// </value> public uint Count { get { return list.Count; } } /// <summary> /// Occurs when a new patient is added to the list. /// </summary> /// <remarks> /// This event typically occurs when <see cref="Add"/> has successfully /// added a new patient. The data is passed through an instance of the /// <see cref=”PatientAddedEventArgs”/> class. /// </remarks> public event EventHandler Added; } /// <summary> /// Holds the data associated with the <see cref="Added"/> event. /// </summary> public class PatientAddedEventArgs : EventArgs { public PatientAddedEventArgs(Patient newPatient) { // Code left out for brevity } /// Remainder of the class left out for brevity... } } |
8.2 标识符大小写
标示符 |
大小写 |
示例/说明 |
namespace |
Pascal |
Ztesoft.BS.Model,以公司名.模块名[.功能[.设计]]命名 |
class |
Pascal |
AppDomain |
enum |
Pascal |
ErrorLevel,enum内的值按照常量来编码 |
delegate |
Pascal |
MouseEventHandler,以Handler为后缀 |
event |
Pascal |
ValueChanged |
Exception |
Pascal |
Exception为后缀 |
常量 |
全部大写 |
RED_VALUE |
接口 |
Pascal |
IDisposable,总是以I开头 |
方法 |
Pascal |
ToString |
参数 |
camel |
typeName |
属性(Property) |
Pascal |
BackColor |
受保护的实例字段(Field) |
camel |
backColor 注意:很少使用。属性优于使用受保护的实例字段。 |
公用实例字段(Field) |
Pascal |
BackColor 注意:很少使用。属性优于使用公用实例字段。 |
Attribute |
Pascal |
XmlElementAttribute,最后要以Attribute结束 |
Pascal 大小写
将标识符的首字母和后面连接的每个单词的首字母都大写。可以对三字符或更多字符的标识符使用 Pascal 大小写。例如:
BackColor
Camel 大小写
标识符的首字母小写,而每个后面连接的单词的首字母都大写。例如:
backColor
大写
标识符中的所有字母都大写。仅对于由两个或者更少字母组成的标识符使用该约定。例如:
System.IO
System.Web.UI
8.3 使用XML标记说明类型和成员
SECTION TAGS |
描述 |
位置 |
<summary> |
简短描述 |
type or member |
<remarks> |
描述前提条件和其他附加信息 |
type or member |
<param> |
描述method的参数 |
method |
<return> |
描述method的返回值 |
method |
<exception> |
方法或者属性可能抛出的异常列表 |
method,event or property |
<value> |
描述property能够接受的或者返回的数据类型 |
property |
<example> |
type或者member的范例(代码或者文本) |
type or |
<seealso> |
增加一个实体到See Also段 |
type or member |
<overload> |
为method的overload提供一个摘要 |
在重载列表中的第一个方法 |
MARKUP TAGS |
描述 |
<code> |
对代码范例改变缩进策略 |
<c> |
改变字体为等宽字体 |
<para> |
创建一个新段落 |
<list> |
创建一个列表 |
<b> |
粗体 |
<i> |
斜体 |
8.4 命名空间约定
命名空间 |
说明 |
备注 |
Ztesoft.BS |
前缀 |
|
Ztesoft.BS.Commons |
前后台公用 |
|
Ztesoft.BS.Commons.Logging |
日志 |
|
Ztesfot.BS.Commons. XmlWebFuncHelper |
XML自动序列化 |
|
Ztesoft.BS.Exceptions |
全局异常类 |
|
Ztesoft.BS.Web |
Web应用 |
|
Ztesoft.BS.PPM |
产品管理后台 |
|
Ztesoft.BS.CM |
客户管理后台 |
|
Ztesoft.BS.CCM |
客服管理后台 |
|
Ztesoft.BS.DAO |
后台DAO公用 |
|
Ztesoft.BS.Model |
后台DTO公用 |
|
后台模块举例 |
||
Ztesoft.BS.CCM.OrderManagement |
订单管理 |
应用程序异常、常量定义也放在该命名空间 |
Ztesoft.BS.CCM.OrderManagement.BL |
订单管理业务逻辑层 |
|
Ztesoft.BS.CCM.OrderManagement.DAL |
订单管理数据访问层 |
|
Ztesoft.BS.CCM.OrderManagement.SA |
订单管理服务代理层 |
8.5 类名后缀约定
类名 |
说明 |
备注 |
XxxxDto |
数据传输对象 |
|
XxxDAOFactory |
DAO工厂 |
|
IXxxxDAO |
DAO接口 |
|
XxxxDAOOracle/XxxxDAOInfomix |
DAO的数据库实现 |
|
XxxxServiceAgent |
服务代理 |
|
XxxxManager |
业务逻辑 |
|
XxxxService |
服务接口 |
|
XxxxFacade |
业务正面 |
|
BSXxxxException |
应用程序异常 |
8.6 数据传输对象(DTO)编码约定
1. DTO的类名使用Dto后缀
2. 数据库中每一张表对应一个DTO
3. DTO中数据类型除String外,都使用Ztesoft.BS.Commons.Model.BaseType命名空间中的Wrapper类
数据库类型 |
.Net数据类型 |
默认值 |
备注 |
varchar/char |
String |
null |
|
number(m,n) |
BaseType.Double |
null |
|
number(n) |
BaseType.Long |
null |
|
Date |
BaseType.DateTime |
null |
4. DTO中包含DTO,属性名使用DTO完整类型;DTO包含DTO数组,属性名使用DTO完整类名+List后缀
AcctDto包含CustDto
private CustDto custDto; public CustDto CustDto { get {return custDto;} set {this.custDto = value;} } |
CustDto包含多个AcctDto
private AcctDto[] acctDtoList; public AcctDto[] AcctDtoList { get {return acctDtoList;} set {this. acctDtoList = value;} } |
9 参考文献
[1] Vic Hartog and Dennis Doomen. Coding Standard: C#. Philips Electronics, 2003
[C1]待完善