1、4.7. 空格 括号和它里面的字符之间不要出现空格。括号应该和它前边的关键词留有空格,如:while (true) ; 但是方法名和左括号之间不要有空格。 参数之间的逗号后要加一空格。如:method1(int i1, int i2) for语句里的表达式之间要加一空格。for (expr1; expr2; expr3) 二元操作符和操作数之间要用空格隔开。i + c; 强制类型转换时,在类型和变量之间要加一空格。(int) i ;5. 注释5.1. 注释的基本约定 注释应该增加代码的清晰度; 保持注释的简洁,不是任何代码都需要注释的,过多的注释反而会影响代码的可读性。 注释不要包括其他的特殊
2、字符。 建议先写注释,后写代码,注释和代码一起完成 如果语句块(比如循环和条件分枝的代码块)代码太长,嵌套太多,则在其结束“”要加上注释,标志对应的开始语句。如果分支条件逻辑比较复杂,也要加上注释。 在VS2005环境中通过配置工程编译时输出XML文档文件可以检查注释的完整情况,如果注释不完整会报告编译警告;5.2. 注释类型5.2.1. 块注释 主要用来描述文件,类,方法,算法等,放在所描述对象的前边。具体格式以IDE编辑器输入“/”自动生成的格式为准,另外再附加我们自定义的格式,如下所列:/ 作者,创建日期,修改日期对类和接口的注释必须加上上述标记,对方法可以视情况考虑5.2.2. 行注释
3、 主要用在方法内部,对代码,变量,流程等进行说明。整个注释占据一行。5.2.3. 尾随注释 与行注释功能相似,放在代码的同行,但是要与代码之间有足够的空间,便于分清。例:int m = 4 ; / 注释 如果一个程序块内有多个尾随注释,每个注释的缩进要保持一致。5.3. 注释哪些部分项目注释哪些部分参数参数用来做什么任何约束或前提条件字段/属性字段描述类类的目的 已知的问题类的开发/维护历史接口目的它应如何被使用以及如何不被使用局部变量用处/目的成员函数注释成员函数做什么以及它为什么做这个哪些参数必须传递给一个成员函数成员函数返回什么任何由某个成员函数抛出的异常成员函数是如何改变对象的包含任何
4、修改代码的历史如何在适当情况下调用成员函数的例子适用的前提条件和后置条件成员函数内部注释控制结构代码做了些什么以及为什么这样做难或复杂的代码处理顺序5.4. 程序修改注释 新增代码行的前后要有注释行说明,对具体格式不作要求,但必须包含作者,新增时间,新增目的。在新增代码的最后必须加上结束标志; 删除代码行的前后要用注释行说明,删除代码用注释原有代码的方法。注释方法和内容同新增;删除的代码行建议用#region XXX #endregion 代码段折叠,保持代码文件干净整洁 修改代码行建议以删除代码行后再新增代码行的方式进行(针对别人的代码进行修改时,必须标明,对于自己的代码进行修改时,酌情进行
5、)。6. 命名6.1. 命名的基本约定 要使用可以准确说明变量/字段/类的完整的英文描述符,如firstName。对一些作用显而易见的变量可以采用简单的命名,如在循环里的递增(减)变量就可以被命名为 ” i ”。 要尽量采用项目所涉及领域的术语。 要采用大小写混合,提高名字的可读性。为区分一个标识符中的多个单词,把标识符中的每个单词的首字母大写。不采用下划线作分隔字符的写法。有两种适合的书写方法,适应于不同类型的标识符:PasalCasing:标识符的第一个单词的字母大写;camelCasing:标识符的第一个单词的字母小写。下表描述了不同类型标识符的大小写规则: 标识符大小写示例命名空间Pa
6、scalnamespace Com.Techstar.ProductionCenter类型public class DevsListpublic interface ITableModel方法public void UpdateData()属性Public int Length事件public event EventHandler Changed;私有字段Camelprivate string fieldName;非私有字段public string FieldName;枚举值FileModeAppend参数public void UpdateData(string fieldName)str
7、ing fieldName; 避免使用缩写,如果一定要使用,就谨慎使用。同时,应该保留一个标准缩写的列表,并且在使用时保持一致。 对常见缩略词,两个字母的缩写要采用统一大小写的方式(示例:ioStream,getIOStream);多字母缩写采用首字母大写,其他字母小写的方式(示例:getHtmlTag); 避免使用长名字(最好不超过 15 个字母)。 避免使用相似或者仅在大小写上有区别的名字。6.2. 各种标示符类型的命名约定6.2.1. 程序集命名 公司域名(Techstar)+ 项目名称 + 模块名称(可选),例如:中心系统程序集:Techstar.ProductionCenter;中心
8、系统业务逻辑程序集:Techstar. ProductionCenter.Business;6.2.2. 命名空间命名 采用和程序集命名相同的方式:公司域名(Techstar)+ 项目名称 + 模块名称。 另外,一般情况下建议命名空间和目录结构相同。中心系统:中心系统下的用户控件:Techstar.ProductionCenter.UserControl;中心系统业务逻辑:中心系统数据访问:Techstar. ProductionCenter.Data;6.2.3. 类和接口命名 类的名字要用名词; 避免使用单词的缩写,除非它的缩写已经广为人知,如HTTP。 接口的名字要以字母I开头。保证对接
9、口的标准实现名字只相差一个“I”前缀,例如对IComponent的标准实现为Component; 泛型类型参数的命名:命名要为T或者以T开头的描述性名字,例如:public class Listpublic class MyClass 对同一项目的不同命名空间中的类,命名避免重复。避免引用时的冲突和混淆;6.2.4. 方法命名 第一个单词一般是动词 如果方法返回一个成员变量的值,方法名一般为Get+成员变量名,如若返回的值 是bool变量,一般以Is作为前缀。另外,如果必要,考虑用属性来替代方法,具 体建议见10.1.2节; 如果方法修改一个成员变量的值,方法名一般为:Set + 成员变量名。
10、同上,考虑 用属性来替代方法;6.2.5. 变量命名 按照使用范围来分,我们代码中的变量的基本上有以下几种类型,类的公有变量;类的私有变量(受保护同公有);方法的参数变量;方法内部使用的局部变量。这些变量的命名规则基本相同,见标识符大小写对照表。区别如下:i. 类的公有变量按通常的方式命名,无特殊要求;ii. 类的私有变量采用两种方式均可:采用加“m”前缀,例如mWorkerName;iii. 方法的参数变量采用camalString,例如workerName;iv. 方法内部的局部变量采用camalString,例如workerName; 不要用_或&作为第一个字母; 尽量要使用短而且具有意
11、义的单词; 单字符的变量名一般只用于生命期非常短暂的变量。i,j,k,m,n一般用于integer;c,d,e 一般用于characters;s用于string 如果变量是集合,则变量名要用复数。例如表格的行数,命名应为:RowsCount; 命名组件要采用匈牙利命名法,所有前缀均应遵循同一个组件名称缩写列表6.3. 组件名称缩写列表缩写的基本原则是取组件类名各单词的第一个字母,如果只有一个单词,则去掉其中的元音,留下辅音。缩写全部为小写。组件类型缩写例子LabelLbllblNoteTextBoxTxttxtNameButtonBtnbtnOKImageButtonIbibOKLinkBut
12、tonLblbJumpHyperLinkHlhlJumpDropDownListDdlddlListCheckBoxCbcbChoiceCheckBoxListCblcblGroupRadioButtonRbrbChoiceRadioButtonListRblrblGroupImageImgimgBeautyPanelPnlpnlTreeTreeViewTvtvUnitWebComTableWctwctBasicImageDateTimeInputDtidtiStartComboBoxcbListMyImageButtonMibmibOKWebComm.TreeViewPageBarPbpbM
13、aster7. 声明 每行要只有一个声明,如果是声明i,j,k之类的简单变量可以放在一行; 除了for循环外,声明要放在块的最开始部分。for循环中的变量声明可以放在for语句中。for(int i = 0; I 10; i+) 。8. 表达式和语句 每行建议只有一条语句。 if-else,if-elseif语句,任何情况下,都应该有“”,“”,格式如下:if (condition) statements; else if (condition) else for语句格式如下:for (initialization; condition; update) 如果语句为空: update) ; w
14、hile语句格式如下:while (condition) 如果语句为空:while (condition); do-while语句格式如下:do switch语句,每个switch里都应包含default子语句,格式如下:switch (condition) case ABC:/* falls through */case DEF:break;case XYZ:default: try-catch语句格式如下:try catch (ExceptionClass e) finally 9. 类型设计规范 要确保每个类型由一组定义明确,相互关联的成员组成,而不仅仅是一些无关功能的随 机集合;9.1
15、. 类型和命名空间 要用命名空间把类型组织成相关域的层次结构。界面层:业务逻辑层:Techstar.ProductionCenter.Business;数据访问层:Techstar.ProductionCenter.Data; 避免过深的命名空间; 避免太多的命名空间;9.2. 类型和接口的选择 要优先采用类而不是接口。接口的缺点在于语义变化时改变困难。注意接口并不是协定,把协定和实现分开并非一 定用接口实现,用基类和抽象类同样可以表达; 建议使用抽象类而不是接口来解除协定与实现间的偶合; 要定义接口,来实现类似多重继承的效果;精心定义接口的标志是一个接口只做一件事情。关键是接口的协定需要保持
16、不变, 如果一个接口包含太多功能,那么这个胖接口产生变化的机会就会大得多。9.3. 抽象类设计: 不要在抽象类中定义公有的或内部受保护的构造函数。因为抽象类无法实例化,所以这 种设计会误导用户; 要为抽象类定义受保护的构造函数或内部构造函数;9.4. 静态类设计静态类是一个只包含静态成员的类,它提供了一种纯面向对象设计和简单性之间的一个权衡,广泛用来提供类似于全局变量或一些通用功能。 要少用静态类。静态类应该仅用作辅助类; 避免把静态类当作杂物箱。每个静态类都应该有其明确目的; 不要在静态类中声明或覆盖实例成员;9.5. 枚举设计 要用枚举来加强那些表示值的集合的参数,属性以及返回值的类型性;
17、 要优先使用枚举而不是静态常量。/不好的写法public static class Colorpublic static int Red = 0;public static int Green = 1;public static int Blue = 2;/好的写法public enum ColorRed,Green,Blue 不要把枚举用于开放的场合,例如操作系统的版本,朋友的名字等; 枚举最后一个值不要加逗号; 枚举中不要提供为了今后使用而保留的枚举值;10. 成员设计规范方法,属性,事件,构造函数以及字段等统称为成员。10.1. 成员设计的一般规范10.2. 方法的重载规范; 避免在重载
18、中随意的给参数命名。如果两个重载中的某个参数表示相同的输入,那么该参数的名字应该相同。public class Stringpublic int IndexOf(string value) .public int IndexOf(string value, int startIndex) .public int IndexOf(string str, int startIndex) . 避免使重载成员的参数顺序不一致。在所有的重载中,同名参数应该出现在相同的位置。 例如:public class EventLogpublic EventLog();public EventLog(string
19、logName);public EventLog(string logName, string machineName);public EventLog(string logName, string machineName, string source); 较短的重载应该仅仅调用较长的来实现。另外,重载如果需要扩展性,把最长重载 做成虚函数。public int IndexOf(string s)/调用return IndexOf(s, 0);public int IndexOf(string s, int startIndex)return IndexOf(s, startIndex, s.
20、Length);public virtual int IndexOf(string s, int startIndex, int Count)/实际的代码 要允许可选参选为null。这样做是为了避免调用者调用之前需要检查参数是否null。例 如:/允许为null时的调用DrawGeometry(brush, pen, geometry);/不允许为null时的调用if (geometry = null) DrawGeometry(brush, pen);else DrawGeometry(brush, pen, geometry);10.3. 属性和方法的选择 基本原则是方法表示操作,属性表示
21、数据。如果其他各方面都一样,优先使用属性而不 是方法。 要使用属性,如果该成员表示类型的逻辑attribue 如果属性的值存储在内存中,而提供属性的目的仅仅是为了访问该值,要使用属性而不 要使用方法 如果该操作每次返回的结果不同,那么要使用方法。例如来自于.net framework的例子:Guid.NewGuid();DateTime.Now; 如果该操作比访问字段慢一个或多个数量级,要使用方法。 如果该操作有严重的副作用,要使用方法。10.4. 属性的设计规范: 如果不应该让调用方法改变属性值,要创建只读属性; 不要提供只写属性; 要为所有的属性提供合理的默认值,这样可以确保默认值不会导致
22、漏洞或效率低的代 码; 要允许用户以任何顺序来设置属性的值; 避免在属性的获取方法抛出异常。属性的获取方法应该是个简单的操作,不应该有任何的条件。如果一个获取方法会抛出 异常,按么可能它更应该设计为方法。10.5. 构造函数的设计规范 建议提供简单的构造函数,最好是默认构造函数。简单的构造函数增强易用性; 考虑扩展性,如果构造函数设计的不自然,建议用静态的工厂方法来替代构造函数; 要把构造函数的参数用作设置主要属性的便捷方法。如果构造函数参数仅用来设置属 性,应和属性名称相同。仅有大小写的区别; 要在构造函数中做最少的工作。任何其他处理应该推迟到需要的时候; 要在类中显示的声明公用的默认构造函
23、数,如果这样的构造函数是必须的。如果没有显示默认构造函数,填加有参数构造函数时往往会破坏已有使用默认构造函数 的代码; 避免在对象的构造函数内部调用虚成员。这样在扩展设计的时候会导致难以理解的现 象;10.6. 字段设计规范 不要提供公有的或受保护的字段。代之以属性来访问字段; 要只用常量字段来表示永远不会改变的量。否则会导致兼容性问题。下面是正确的例子:public struct Int32public const int MaxValue = 0x7fffffff;public const int MinValue = unchecked(int)0x80000000); 要用公有的静态只
24、读字段来定义预定义的对象实例。public struct Colorpublic static readonly Color Red = new Color(0x0000FF);10.7. 参数的设计规范 要用类结构层次中最接近基类类型来作为参数的类型,同时要保证该类型能够提供成员 所需的功能。要设计一个集合遍历的方法,那么参数应该是IEnbumerable为参数,而不应该是IList, 这样方法具有更强的适应性。 不要使用保留参数。如果将来需要更多的参数,那么可以增加重载成员。public void Method(string reserved, SomeOption option);pub
25、lic void Method(SomeOption option);/将来填加public void Method(SomeOption option, string path);10.7.1. 参数设计中枚举和布尔参数的选择规范 要用枚举。在代码阅读,书写中,枚举都比布尔的可读性好很多。/使用布尔型,阅读的时候不会轻易了解参数的含义FileStream f = File.Open(“1.txt”, true, false);/使用枚举型FileStream f = File.Open(“1.txt”,CasingOptions.CaseSenstive, FileMode.Open); 不要使用布
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1