CodingStdCS_treC#编程规范(烟台创迹软件).doc_第1页
CodingStdCS_treC#编程规范(烟台创迹软件).doc_第2页
CodingStdCS_treC#编程规范(烟台创迹软件).doc_第3页
CodingStdCS_treC#编程规范(烟台创迹软件).doc_第4页
CodingStdCS_treC#编程规范(烟台创迹软件).doc_第5页
已阅读5页,还剩25页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

C#编程规范烟台创迹软件C#编程规范2006年11月3日最新版1. 方针这份规范的制定方针是,对写出易读的代码提供支持。在实际的编码中,为使所有的C#项目开发成员依据该标准编写出易读性强的代码。请大家认真阅读,遵守此规范。2. 文件构成(1) 文件名对于Public类,以它的类名做成一个文件。例:把public class Customer放入Customer.cs类文件里面。封装内的非公共类,可以包含在那个主要被使用的公共类的文件里。异常处理类,多个处理类可以放在一个文件里。(2) 文件的位置在确定了项目的根目录后,在各个目录层次连接的地方放入命名空间的“.”。但是,对应于solution/project命名空间的层次,在目录里使用solution名/project名。例:命名空间:CompanyName.OrganizationName.TechnologyName.CoreFeatureName.SubFeatureName对应于solution SolutionName 的命名空间:TechnologyName对应于项目ProjectName 的命名空间:CoreFeatureName上述命名空间所对应的代码存放的路径:C:CompanyNameOrganizationNameSolutionNameProjectNameSubFeatureName(3) 测试类名类ClassName的单元测试类名为ClassNameTest。Solution的单元测试的名称命名为SolutionNameTests。例:类Customer作成测试类CustomerTest.cs例: Solution CsSample作成CsSampleTests.csproj理由:可以保持命名的一致性。测试代码可以成为使用方法的样本和现成的例子。(4) 测试类的位置在和被测试类相同层次的目录及子目录里,配置测试类的位置。例:被测试类的位置:C:CompanyNameOrganizationNameSolutionNameProjectName测试类的位置:C:CompanyNameOrganizationNameSolutionNameSolutionNameTestsC:CompanyNameOrganizationNameSolutionNameSolutionNameTestsProjectNameTests理由:如果不放在物理位置相近的地方,很容易忘掉。至于和成品代码分离的时候,使用其他工具(NAnt的build文件等)可能会有所调整。3. 命名规则(5) 命名空间使用“公司名.组织名.技术名.功能名”的形式。另外,技术名和Solution名、功能名和项目 (Project) 名要一一对应。using CompanyName.OrganizationName.TechnologyName.FeatureName(6) 文件名公共类名和文件名必须相同。(区分大小写)(7) 类名开头是大写。以后的单词首字母大写。class PascalCasing(8) 异常处理类的类名在类名最后加上Exception。class ClassNameEndsWithException(9) 接口名与类名的命名方法相同。经常在开头添加“I”。interface INameOfInterface另外,在类里面使用到的功能,也加到名字里。功能用形容词来表示,用-able结尾。例: IEnumerable, ICloneable, IXmlSerializable, (10) 密封类名 要和Interface进行必要的区别,在末尾添加“Impl”。class ClassNameEndsWithImpl(11) 抽象类名在没有恰当的名字来表示抽象类时,以Abstract开头,在其后跟上可以联想到的子类的名字。abstract class AbstractBeforeSubClassName(12) 常量(Const) 用大写字母或者是用下划线“_”连接大写字母来命名。const int UPPERCASE = 0;const int UPPERCASE_WITH_UNDERSCORES = 0;(13) 枚举型(enum)开头大写,其后单词首字母大写。enum PascalCasing用枚举型表示多个Bit Field时,加上FlagsAttribute。Flags enum PascalCasings(14) 枚举值开头大写,其后单词首字母大写。PascalCasing(15) 事件(Event)名开头大写,其后单词首字母大写。event PascalCasing()(16) 方法(Method)名开头大写,其后单词首字母大写。void PascalCasing()object PascalCasing()(17) Factory方法(新建对象)X NewX()X CreateX()(18) Convert方法 (转换对象)X ToX()(19) 属性名开头大写,其后单词首字母大写。object PascalCasing()(20) 返回Boolean变量的方法Is +形容词、Can +动词、Has +过去分词、动词第三人称单数、动词第三人称单数+ 名词。好的例子:bool IsEmpty()bool CanGet()bool HasChanged()bool Contains(object x) bool ContainsKey(string key)不好的例子:bool Empty()/可以理解为“对空进行操作”的动词性意思。bool CheckXXX()/ 难以判断true代表的含义。理由: 使if, while语句的条件易读,并且true代表的意思容易理解。(21) Bool变量形容词、Is +形容词、Can +动词、Has +过去分词、动词第三人称单数、动词第三人称单数+ 名词。bool isEmpty;bool dirty;bool containsMoreElements;(22) 英语和日语基本上所有关键字的名字都是英语,另外,在项目的整个生命周期内,可以做成日英对照词典。(23) 名称的对称性在命名类和方法时,请留意以下的英语的对称性。Add / RemoveInsert / DeleteGet / SetStart / StopBegin / EndSend / ReceiveFirst / LastGet / ReleasePut / GetUp / DownShow / HideSource / TargetOpen / CloseSource / DestinationIncrement / DecrementLock / UnlockOld / NewNext / Previous(24) 循环计数器(Loop Counter)当作用域(通用范围)很小时,循环计数器就可以顺序地使用 i, j, k等名字。(25) 小作用域的变量命名当变量名的作用域很小时,可以使用类型名称的缩写。例: DataSet ds = new DataSet();(26) 名称要能表达变量的意思。通过变量名就能明白变量的作用。不好的例子: Copy(string s1, string s2)好 的 例子: Copy(string source, string destination)(27) 没有实际意思的名字对于Info, Data, Temp, Str, Buf等这些名字,需要重新考虑换名字。不好的例子:double temp = Math.Sqrt(b*b - 4*a*c);好的例子: double determinant = Math.Sqrt(b*b - 4*a*c);(28) private / protected / internal / protected internal作用域内的实例化变量开始小写,以后单词首字母大写。使用前缀/ 后缀的场合,需要考虑变量名的易读性。在用户定义的对象类型里,不要使用匈牙利标记法,使用Camel标记法。其他的使用匈牙利标记法。private object objCasing;protected object objCasing;internal People peopleCasing; /People是用户定义的对象protected internal People peopleCasing;(29) Public作用域内的实例化变量开头字母大写,其后单词首字母大写。尽量不要使用。public object PascalCasing;(30) private / protected / internal / protected internal作用域内的公共变量开始小写,其后单词首字母大写。使用前缀/后缀的场合,需要考虑变量名的易读性。在用户自定义的对象类型中,不要使用匈牙利标记法,应该使用Camel标记法。其他的使用匈牙利标记法。private static object camelCasing; protected static object camelCasing;internal static People peopleCasing; /People是用户定义的对象protected internal static People peopleCasing;(31) public作用域内的公共变量开头字母大写,其后单词首字母大写。尽量不要使用。public static object PascalCasing;(32) 局部(Local)变量开始小写,其后单词首字母大写。在用户自定义的对象类型中,不要使用匈牙利标记法,应该使用Camel标记法。其他的使用匈牙利标记法。object objCasing;(33) 大小写命名时虽然区分大写字母和小写字母,但不能只是依靠这样来区别不同的名称。4. GuideLine(34) #Region / #End Region 预处理指令代码声明在Region / #End Region directive的领域里,其中包含关于该领域的说明。例:#Region 实例化变量 private string name;#End Region#Region Constructor public MyClass(string name) = name; #End Region(35) 方法/属性的声明在方法/属性的声明里,要明确地指定作用域。()长行一行的字符数最多是100位,如果超过100位就要进行分割。分割的依据可以是:(1)利用局部变量,(2) 在算术运算符/联结运算符处换行,(3)在逗号处换行(4)在优先级低的算符前换行。例如:double length = Math.Sqrt(Math.Pow(new Random().NextDouble(), 2.0) + Math.Pow(new Random().NextDouble(), 2.0); 方針(1)double xSquared = Math.Pow(new Random().NextDouble(), 2.0);double ySquared = Math.Pow(new Random().NextDouble(), 2.0);double length = Math.Sqrt(xSquared + ySquared); 方針(2) double length = Math.Sqrt(Math.Pow(new Random().NextDouble(), 2.0), Math.Pow(new Random().NextDouble(), 2.0); 方針(3)LongMethodSignature(value0, value1, value2, value3, value4, value5); 方針(4) return (this is obj) _ | (obj is Class1 _ and this.Field = obj.Field);(37)长行的类声明类的声明较长的情况下在逗号,冒号处换行。例:如果是public class LongNameClassImplemenation : AbstractImplementation, IXmlSerializable, Icloneable那么:public class LongNameClassImplemenation :AbstractImplementation,IXmlSerializable, ICloneable(38)长行的方法声明方法的声明很长时在逗号处进行换行。例:public void LongMethodSignature(int a, int b, int c, int d, int e, int f) (39)抽象类和接口尽量不使用抽象类(abstract Class)而是多使用接口(interface)。abstract Class只有在既有已密封方法又有抽象方法的情况下使用。理由:接口(interface)允许多继承,而类(Class)只能是单继承。如果只是继承了一个类,那么可惜不能再从其他类进行继承。(40)公共变量实例变量,尽量不用public修饰,而是设置合适的属性。理由:面向对象的标准。类的内部状态是不能被随意访问的。但是,如果全部满足下列条件,用public修饰实例变量,使之被直接访问也可以:l 如果那个实例变量与其他的实例变量是相互独立的,单独地改变它不会影响内部的整合性。l 一定书写get/set访问器l 依据将来传递时不被改变的原则进行接口变量的实装即使不适合上述条件,但在非常关注效率的情况下,也可以没有这个限制。(但是,请慎重对待)(41)初始化参照不要初始化为空值,而且不要进行两次初始化。不好的例子:public class PoorInitialization private string name = initial_name; public PoorInitialization() name = initial_name; 理由:尽量减少与初始化有关的错误。(42)避开static变量尽量不用static变量(类变量)。理由:static变量,可以说是半全局变量。这会导致代码的相互关系复杂化,会产生一定的副作用。(43)private 与protected比起private,protected更常用。理由:定义为private的成员对于所在类以外的成员而言是不能访问的。所以用户也就不能在子类中对它进行访问,作进一步的处理。但是:更喜欢使用private。若用protected后,改变时会影响到整个类的继承关系。(44)get/set访问器不要胡乱地作成实例的属性(get/set访问器)并赋予public公共访问级别。必要时,要做成某种属性/方法。理由:实例变量多是相互依存的,类的内部整合性不能破坏。(45)变量隐藏不要使用和基类的变量名相同的变量名。理由:这种情况一般会出现错误。如果是有目的地使用可以这样。(46)public 方法类的公共方法,以自动贩卖机的接口为例,进行易于理解,即使使用方法有误也不会破坏内部整合性的设计。或者可能的情况下根据约定进行设计,用代码来表现类的不变条件,方法的执行前和执行后条件。 (47)状态取得和状态变更的分离要设计的方法只能完成一项功能。特别是不能在一个方法里面既进行状态变更又进行状态取得两种功能。状态变更的方法的返回值 为void因为:、1个方法完成一样功能简单易懂。2、方便进行并行性的控制并易于确保程序不产生意外错误。3、在子类的继承中,便于扩充。(48)this中的return尽管这是为用户使用的方便考虑,还是要尽量避免使用return返回this的方法。理由:A.Meth1().Meth2().Meth3() 这样的连接,一般会产生同步上的问题。(49)方法的多重定义根据参数的类型尽可能的避免方法的重载(参数的个数可以不同),特别,在继承的复杂关系中。例:override void Draw(Rectangle rectangle) override void Draw(Point point):void DrawRectangle(Rectangle rectangle)void DrawPoint(Point point)(50)Equals()和GetHashCode()如果撤销Object.Equals()方法,同时GetHashCode()方法也将被撤销。反之亦然。理由: 为了与哈希表(Hashtable)等相对应。(51)Clone()如果要使用Clone()方法,实例化ICloneable要明确写出来。例:using System;public class Foo : ICloneable public object ICloneable.Clone() Foo myFoo = (Foo) this.Clone(); /. 理由:简单的拷贝存在很多不好的情况。(52)缺省的构造器最好建立缺省的构造器(没有参数)。理由:在使用reflection时,可以利用Assembly.CreateInstance(TypeName)动态地生成对象。(53)抽象类中的抽象方法在abstract(抽象)类中,不写no-op方法,而是明确声明abstract方法。对此设置为protected访问级别,为可能需要的实装做准备,这样可以在子类中实现方法功能。理由:因为.NET的IDE能查出没有实装的abstract方法,可以避免因为忘记实装而产生的错误。(54)对象的同值比较对象进行比较时使用Equals()方法,不能使用“=”。特别是进行字符串的比较时,也不能使用“=”。理由:如果编程者想实现等值比较的话,那就应该使用Equals()。并且,使用String进行比较时在Option Compare Text设定的是比较字符串不区分大小写。原因:在单元测试中,AssertEquals可以使用Equals(),可以简单地书写等值类。(55)声明和初始化局部变量,在声明时就进行初始化。理由:把有关变量的值假定为最小化。不好的例子:void f(int start) int i, j; / 没有赋予初始化值 / 较多的代码 / . i = start + 1; j = i + 1; / 使用i,j / .好的例子:void f(int start) / 较多的代码 / . int i = start + 1; int j = i + 1; / 使用i,j / . (56)局部变量不能重复利用如果要重复使用局部变力,一定要重新进行声明并初始化。理由:把有关变量的值假定为最小化。可以使编译程序达到最优化。不好的例子:void f(int n, int delta) int i; / 没有进行初始化 for (i = 0; i n; i+) / 使用i for (i = 0; i n; i+) / 再次使用i if (.) break; if (i != n - 1) /使用i进行循环的最后判断 / . i = n - delta * 2; / 再次使用 /. 好的例子:void f(int n, int delta) for (int i = 0; i n; i+) / 使用i bool found = false; for (int j = 0; i n; i+) / 使用j if (.) found = true; break; if (found) / . int total = n - delta * 2; / 利用其他的变量 /.(57)大小比较运算符 最好使用“”、”“、”=“理由:统一大小方向,右侧的为大的方向,避免混乱。(58)if/while 条件中的 =if,while的条件式中,不能使用“=“理由:几乎所有这样的场合,都会出现错误。(59)castCast形式转换时,尽量使用类型判断语句。例(C为已知类,x是C的一个实例):C cx = null; if (x is C) cx = (C) x; else evasiveAction();/动作方法理由:这时,常常考虑的事情是“对象是不是类的实例呢?”。但是,cast不成功的场合是存在错误的。如果能够判断出来的话,就没有这个限制了。(60)异常类异常类具有范围广大的特点,如果多用的话很容易造成程序流程难以阅读的问题。使用异常类,相对于重新编写新的异常类来说, 应尽可能利用.NET类库中已有的异常类例如IOException, FileNotFoundException, ArgumentException等都是易使用的标准异常。编写新的异常,也要研究这些现有的异常类的接口。(61)改变方法的参数不好原则上讲,方法中的参数是用来输入的,不能作为输出使用。即在方法的内部改变参数的值是不提倡的。不向输出参数代入新的对象。不好的例子:void MoveX(Point p, int dx)p.X = p.X + dx; / 改变了参数(尽量避免)好的例子: void MoveX(Point p, int dx) Point p = New Point(p.X + dx, p.Y); / 这个变量不会传到调用方特殊情况:考虑性能时。(62)方法参数的命名方法的参数应该具有易读性,特别是和实例变量重名的时候,要灵活运用this关键字,而不能牺牲参数的可读性。不好的例子:void Reset(int x_, int y_) x = x_; y = y_;好的例子:/ 不把参数命名为 x_, y_ void Reset(int x, int y)this.x = x;this.y = y; void Reset(int x, int y)_x = x;_y = y; (63)ToString()ToString()方法,能够使用的话,尽量使用因为(调试时):1. Console.Writeline(Object)总能够显示2. 在进行单元测试等时,容易明白错误。(64)避免嵌套使用switch,if/else当在switch语句中又出现了分支结构时,将被认为是不好的设计,重新考虑能否可以使用多态来实现。特别是,当同样的switch语句在两处以上出现时,就必须使用多态性、工厂方法(FactoryMethod)或者Prototype模式等 重新设计。If/else的嵌套使用也是一样。并且,当进行Null检查用的同样的if语句多次出现时,也需要考虑使用NullObject模式实现。5、注释(65)有效利用文档注释较多地使用/注释形式的注释,这种注释在VS.NET和CSC中能够转换为XML、HTML的文档。公共的类、方法、属性须要加上/注释。(66)长的注释当注释较长需要在写在多行上时,先在注释的首行用简短的语句表达要说明的意思,然后附加上长的注释。另外,当有必要使用这种长注释时,需要考虑更简单的设计,积极地进行修整。(67)Design by Contract(基于契约的设计)/在这里,契约可以理解为系统的一种说明,比如堆栈的状态,系统异常描述等。在C#中称为契约。为了进行基于契约的设计,需要使用Debug对象的Assert方法。使用Assert方法,可以将契约表示出来。示例:using System.Collections;public class MyStack : Stack private int capacity; private int itemCount; public overrid void Push(Object obj) Debug.Assert(!(obj is null); /进行处理前的条件 / . / . Debug.Assert(this.Contains(obj); / 处理后的条件 public bool Invariant() / 不变条件(如果发生溢出,则输出调用堆栈) Debug.Assert(0 = capacity); Debug.Assert(0 = itemCount); Debug.Assert(itemCount = capacity); return true; 注意:Assert方法不能用作用户的输入检查,Assert是用来捕捉Bug的。6、性能 (68)首先进行测量性能的改善首先从测量开始。根据猜测是不行的。(69)new在.NET中,使用new运算符会花费时间,当在一个子循环中调用了new运算符时,如果必要的话,可以使用输出参数。X GetX() return (new X(this.value);上面是运行比较慢的情况、把使用new运算符安排在调用方,下面的情况比较好:void GetX(X x) x.Value = this.value;(70)给变量赋以null值当产生大量的不被使用的变量时,应为这些变量赋以null值。特别是数组元素(尤其是性能要求严格的情况下)原因:有助于无用空间的回收。7、其他(71)在自己编写新的类之前,与相关人员讨论对于别人编写的类,当某些操作有必要重新定义的时候,与其继承别人的类从新编写一个新的类,或者是将别人编写的类作为实例包含过来编写一个类,不如先和那个类的编写人员进行讨论。如果以通用的形式满足需求,整个工程就能比较紧凑地完成。(72)避免使用复杂的设计如果设计的比较混乱,多数情况是因为没有重视设计的简单化。同样,在以后的可维护性方面也要重视设计简单化。(73)测定之后再进行性能的调整。在最初编写代码的时候不要过多地考虑代码的性能。优先考虑保证代码的可读性。测试之后再进行性能的改善。(74)难以理解的代码不是好的代码编写的代码应该让一般的.NET程序员都能看得懂。像运算符的顺序、有关初始化的规则等,让任何人都能理解不带有疑问,使用()标明运算的顺序,显式地对变量进行初始化,这样就比较容易阅读不好的例子: return cond = 0 ? a b & b c : d = 1;好的例子: return (cond = 0) ? (a b) & (b c) : (d = 1);不好的例子:/ 下面是一个制作单位矩阵的例子,既浪费时间又难以理解for (int i = 1; i = n; i+) for (int j = 1; j = n; j+) mi1, j1 = (i / j) * (j / i); 参考资料Kenji Hiranabe, Java编码标准(原版)http:/objectclub.esm.co.jp/eXtremeProgramming/CodingStd.docWriting Robust Java Code高桥日语译版http:/www.alles.or.jp/torutk/oojava/codingStandard/writingrobustjavacode.htmlWriting Robust Java Code 原版(英语) /javaCodingStandards.html太阳System(株式会社) 中西庸文 VB.NET编码标准http:/ObjectClub.esm.co.jp/eXtremeProgramming/CodingStdVB.doc追加部分1. 事件(Event) 的命名方法A. 禁止使用Hungarian Notation(匈牙利标记法)B. 在结尾的部分加上EventHandlerC. 定义两个参数(即sender,e)D. EventArgument类以EventArgs为结束语, E. 使用的例子)public class ClickedEventArgs : EventArgs int nX;int nY;public ClickedEventArgs(int x, int y)this.nX=x;this.nY=y;public int X get return nX;public int Y get return nY;i. 事件的名称以与此事件的动作相对应的动词命名。ii. 例如) ClickedF. 动作完成之前的事件命名用动名词形式、动作完成之后的事件命名使用动词过去式的形式。i. 错误的命名方法) BeforClose, AfterCloseii. 正确的命名方法) Closing, Closed2. 变量(Variable) 的命名规则A. 使用Hungarian Notation。(匈牙利标记法)BGlobal变量以及Static变量的开头加上字符g C变量命名一般不加“_”。只有在类中声明成员变量时可以加“_” 例)private string m_IdD. Hungarian 标记法3. 其他的 NET Database Object & Special Object 命名规则Object形接頭語备注Object形接頭語备注SqlConnectionoCnArrayListarrarrGradeSqlDataAdapteroApHashtablehsthstAttributeSqlDataReaderoRrStringBuildersbsbMenuSqlCommandoCmDataSetds共通DataRowdr共通DataColumndc共通DataTabledt共通TableCelltc共通DataViewdv共通4. Web Form的命名规则A. Web Control 的命名规则Object形接頭語备注Object形接頭語备注AdrotatorrotrotMenuMainMenumnumnuOptionButtonbtnbtnOKMonthCalendarcalcalThisMonthComboBoxcbocboCountryPictureBoxpicpicPhotoCheckBoxchkchkSubjectPanelpnlpnlCategoryCheckBoxListchklchklJusoProgressBarprgprgStatusCompareValidatorvcompvcompComRichTextBoxrtfrtfNotepadCustomValidatorvcstvcstCheckRadioButtonradoptEducationCrystalReportViewercrvcrvReportRadioButtonListradlrbtnlHobbyDataGriddgrdgrCustomerRepeaterreprepBookDropDownListddlddlNameRequiredFieldValidatorvreqvreqCheckDataListdlstdlstAdressRangeValidatorvrngvrngScopDateTimePickerdtpdtFromDateRegularExpressionValidatorvrexvrexCheckDialogsdlgdlgFileOpenStatusBarstbstbCurrentFormfrmfrmPathTextBoxtxttxtAddressGroupBoxgrpgrpBoxTreeviewtvwtvwOrganHyperLinkhlnkhlnkHomeTabControltabtabBasicInfoImageButtonibtnibtnOKTimerclktmrEventImageimgimgBackToolBartbrtlbMenuListBoxlstlstAddressValidationSummaryvsumnvsumnOKLabellbllblNameXMLxmlxmlDataLinkLabelhlblhlblTitleListviewlvwlvwServiceB. HTML Control命名规则Object形接頭語备注ButtonhbtnhbtnGoCheckBoxhchkhchkHobbyDropDownhddlhddl

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论