《非常好的C#.NET_编程规范.docx》由会员分享,可在线阅读,更多相关《非常好的C#.NET_编程规范.docx(16页珍藏版)》请在三一办公上搜索。
1、c#.NET编程规范目录1前言21.1 编写目的21.2 范围22规范内容221代码格式222命名指南31.1 .1大写样式31.2 区分大小写41.3 缩写51.4 措词51.1 .5避免类型名称混淆6226命名空间命名指南81.2 .7类命名指南91.3 .8类成员变量命名指南922.9 接口命名指南1022.10 属性命名指南1022.11 1枚举类型命名指南102212静态字段命名指南1122.13 参数命名指南1122.14 方法命名指南1222.15 属性命名指南1222.16 事件命名指南132.3注释(COmment)规范141.1 .1模块(类)注释规范141.2 类属性注释
2、规范151.3 3方法注释规范151.4 代码间注释规范153成功的模式163.1 有效地使用这些标准163.2 其它导向成功代码的因素161前百1.1 编写目的为了保证企业编写出的程序都符合相同的规范,保证一致性、统一性而建立的程序编码规范。1.2 范围合用于企业所有基于.NET平台的软件开辟工作。2.规范内容2.1 代码格式令所有的缩进为4个空格,使用VS.NET的默认设置。令在代码中垂直对齐左括号和右括号。if(x=0)(ReSponSe.Write(用户编号必须输入!”);)不允许以下情况:if(x=0)ReSPOnSeNriteC用户编号必须输入!);)或者:if(x=0)Respo
3、nse.Write(用户编号必须输入!*);令为了防止在阅读代码时不得不滚动源代码编辑器,每行代码或者注释在1024*800的显示频率下不得超过一显示屏令当一行被分为几行时,通过将串联运算符放在每一行的末尾而不是开头,清晰地表示没有后面的行是不完整的。令每一行上放置的语句避免超过一条。令在大多数运算符之前和之后使用空格,这样做时不会改变代码的意图却可以使代码容易阅读。例:intj=i+k;而不应写为intj=i+k;令将大的复杂代码节分为较小的、易于理解的模块。2.2 命名指南2.2.1 大写样式使用下面的三种大写标识符约定。Pascal大小写将标识符的首字母和后面连接的每一个单词的首字母都大
4、写。可以对三字符或者更多字符的标识符使用Pascal大小写。例如:BackCoIorCamel大小写标识符的首字母小写,而每一个后面连接的单词的首字母都大写。例如:backColor大写标识符中的所有字母都大写。仅对于由两个或者更少字母组成的标识符使用该约定。例如:System.IOSystem.Web.UI可能还必须大写标识符以维持与现有非托管符号方案的兼容性,在该方案中所有大写字母时常用于枚举和常数值。普通情况下,在使用它们的程序集之外这些字符应当是不可见的。下表汇总了大写规则,并提供了不同类型的标识符的示例。标识符大小写示例类PascalAppDomain枚举类型PascalErrorL
5、evel枚举值PascalFatalError事件PascalValueChange异常类PascalWebException注意总是以EXCePtiOn后缀结尾。只读的静态字段PascalRedValue接口Pascal!Disposable注意总是以I前缀开始。方法PascalToString命名空间PascalSystem.Drawing参数CameltypeName属性PascalBackColor受保护的实例字CameIredValue段注意很少使用。属性优于使用受保护的实例字段。公共实例字段PascalRedValue注意很少使用。属性优于使用公共实例字段。2.2.2 区分大小写为
6、了避免混淆和保证跨语言交互操作,请遵循有关区分大小写的使用的下列规则:令不要使用要求区分大小写的名称。对于区分大小写和不区分大小写的语言,组件都必须彻底可以使用。不区分大小写的语言无法区分同一上下文中仅大小写不同的两个名称。因此,在创建的组件或者类中必须避免这种情况。令不要创建仅是名称大小写有区别的两个命名空间。例如,不区分大小写的语言无法区分以下两个命名空间声明。namespaee.cummings;namespaEe.Cummings;令不要创建具有仅是大小写有区别的参数名称的函数。下面的示例是不正确的。voidMyFunction(stringa,stringA)令不要创建具有仅是大小写
7、有区别的类型名称的命名空间。在下面的示例中,Pointp和POINTP是不适当的类型名称,原因是它们仅是大小写有区别。System.Windows.Forms.PointpSystem.Windows.Forms.POINTp令不要创建具有仅是大小写有区别的属性名称的类型。在下面的示例中,intColor和intCOLOR是不适当的属性名称,原因是它们仅是大小写有区别。intColorget,setintCOLORget,set令不要创建具有仅是大小写有区别的方法名称的类型。在下面的示例中,CalCUlate和Calculate是不适当的方法名称,原因是它们仅是大小写有区别。voidcalcu
8、late()voidCalculate()2.2.3 缩写为了避免混淆和保证跨语言交互操作,请遵循有关区缩写的使用的下列规则:令不要将缩写或者缩略形式用作标识符名称的组成部份。例如,使用GetWindow,而不要使用GetWinc令不要使用计算机领域中未被普遍接受的缩写。令在适当的时候,使用众所周知的缩写替换冗长的词组名称。例如,用Ul作为UserInterface的缩写,用OLAP作为OnTineAnalyticalProcessing的缩写。令在使用缩写时,对于超过两个字符长度的缩写请使用Pascal大小写或者Camel大小写。例如,使用HtmlButton或者HTMLButtono但是,
9、应当大写仅有两个字符的缩写,如,System.10,而不是System.Ioo令不要在标识符或者参数名称中使用缩写。如果必须使用缩写,对于由多于两个字符所组成的缩写请使用Camel大小写,虽然这和单词的标准缩写相冲突。2.2.4 措词避免使用与常用的.NET框架命名空间重复的类名称。例如,不要将以下任何名称用作类名称:SystemCollectionsForms或者UIo有关.NET框架命名空间的列表,请参阅类库。此外,避免使用和以下关键字冲突的标识符。AddHandlerAddressOfAliasAndAnsiAsAssemblyAutoBaseBooleanByRefByteByValC
10、allCaseCatchCBoolCByteCCharCDateCDecCDblCharCIntClassCLngCObjConstCShortCSngCStrCTypeDateDecimalDeclareDefaultDelegateDimDoDoubleEachElseElseIfEndEnumEraseErrorEventExitExternalSourceFalseFinalizeFinallyFloatForFriendFunctionGetGetTypeGotoHandlesIfImplementsImportsInInheritsIntegerInterfaceIsLetLibL
11、ikeLongLoopMeModModuleMustInheritMustOverrideMyBaseMyClassNamespaceNewNextNotNothingNotInheritableNotOverridab1eObjectOnOptionOptionalOrOverloadsOverridableOverridesParalnArrayPreservePrivatePropertyProtectedPublicRaiseEventReadOnlyReDimRegionREMRemoveHandlerResumeReturnSelectSetShadowsSharedShortSi
12、ngleStaticStepStopStringStructureSubSyncLockThenThrowToTrueTryTypeOfUnicodeUntilvolatileWhenWhileWithWithEventsWriteOnlyXorevalextendsinstanceofpackagevar2.2.5 避免类型名称混淆不同的编程语言使用不同的术语标识基本托管类型。类库设计人员必须避免使用语言特定的术语。请遵循本节中描述的规则以避免类型名称混淆。使用描述类型的含义的名称,而不是描述类型的名称。如果参数除了其类型之外没有任何语义含义,那末在这种罕见的情况下请使用普通性名称。例如,支
13、持将各种数据类型写入到流中的类可以有以下方法。voidWrite(doublevalue);voidWrite(floatvalue);voidWrite(longvalue);voidWrite(intvalue);voidWrite(shortvalue);不要创建语言特定的方法名称,如下面的示例所示。voidWrite(doubledoubleValue);voidWrite(floatfIoatVaIue);voidWriteflongIongVaIue);voidWritefintintVale);voidWrite(shortShortVaIue);如果有必要为每一个基本数据类型创
14、建惟一命名的方法,那末在这种极其罕见的情况下请使用通用类型名称。下表列出基本数据类型名称和它们的通用替换。C#类型名VisualBasicJScript类型VisualC+类Ilasm.exe表示形通用类型名称类型名称名称型名称式称sbyteSBytesBytecharint8SBytebyteBytebyteunsignedcharunsignedint8ByteshortShortshortshortintl6Intl6ushortUIntl6ushortunsignedunsignedintl6UIntl6shortintIntegerintintint32Int32uintUInt32
15、uintunsignedintunsignedint32UInt32longLonglong_int64int64Int64ulongUInt64ulongunsignedunsignedint64UInt64_int64floatSinglefloatfloatfloat32SingledoubleDoubledoubledoublefloat64DoubleboolBooleanbooleanboolboolBooleancharCharcharwchar_tcharCharstringStringstringStringstringStringobjectObjectobjectObje
16、ctobjectObject例如,支持将从流读取各种数据类型的类可以有以下方法。doubleReadDoubIeO;floatReadSingIef);longReadlnt64();intReadlnt32();shortReadlntl6();前面的示例优于下面的语言特定的替换。doubleReadDoubIeO;floatReadFIoatf);longReadLong();intReadlnt();shortReadShortQ;2.2.6 命名空间命名指南命名命名空间时的普通性规则是使用公司名称,后跟技术名称和可选的功能与设计,如下所示。CompanyName.TechnologyN
17、ame.Feature.Design例如:Microsoft.MediaMicrosoft.Media.Design给命名空间名称加之公司名称或者其他知名商标的前缀可以避免两个已经发布的命名空间名称相同的可能性。例如,Microsoft.Office是由Microsoft提供的OfficeAutomationClasses的一个适当的前缀。在第二级分层名称上使用稳定的、公认的技术名称。将组织层次架构用作命名空间层次架构的基础。命名一个命名空间,该命名空间包含为具有.Design后缀的基命名空间提供设计时功能的类型。例如,System.Windows.Forms.Design命名空间包含用于设计
18、基于System.Windows.Forms的应用程序的设计器和相关的类。嵌套的命名空间应当在包含它的命名空间中的类型上有依赖项。例如,System.Web.UI.Design中的类依赖于System.Web.UI中的类。但是,System.Web.UI中的类不依赖于System.UI.Design中的类。应当对命名空间使用Pascal大小写,并用句点分隔逻辑组件,如Microsoft.Office.PowerPoint中所示。如果您的商标使用非传统的大小写,请遵循您的商标所定义的大小写,即使它与规定的Pascal大小写相背离。例如I,命名空间NeXT.WebObjects和ee.Cummin
19、gs阐释了对于Pascal大小写规则的适当背离。如果在语义上适当,使用复数命名空间名称。例如,使用SyStem.Collections而不是System.Collectiono此规则的例外是商标名称和缩写。例如,使用System.IO而不是System.IOso不要为命名空间和类使用相同的名称。例如,不要既提供Debug命名空间也提供Debug类。最后,请注意命名空间名称不必非得与程序集名称相似。例如,如果命名程序集MyCompany.MyTechnology.dll,它没有必要非得包含MyCompany.MyTechnology命名空间。2.2.7类命名指南以下规则概述命名类的指南:令使用名
20、词或者名词短语命名类。令使用Pascal大小写。令少用缩写。令不要使用类型前缀,如在类名称上对类使用C前缀。例如,使用类名称FileStream,而不是CFileStreamo令不要使用下划线字符(_)。令有时候需要提供以字母I开始的类名称,虽然该类不是接口。只要I是作为类名称组成部份的整个单词的第一个字母,这便是适当的。例如,类名称IdentityStore是适当的。令在适当的地方,使用复合单词命名派生的类。派生类名称的第二个部份应当是基类的名称。例如,App1icationException对于从名为Exception的类派生的类是适当的名称,原因是ApplicationException
21、是一种Exception。请在应用该规则时进行合理的判断。例如,Button对于从Control派生的类是适当的名称。尽管按钮是一种控件,但是将Control作为类名称的一部份将使名称不必要地加长。卜.面是正确命名的类的示例。publicclassFileStreampublicclassButtonpublicclassString2.2.8 类成员变量命名指南类成员变量加m_前缀,如:intm_ContentLengtho2.2.9 接口命名指南以下规则概述接口的命名指南:令用名词或者名词短语,或者描述行为的形容词命名接口。例如,接口名称!Component使用描述性名词。接口名称Icus
22、toniAttributeProvider使用名词短语。名称IPerSiStabIe使用形容词。令使用Pascal大小写。令少用缩写。令给接口名称加之字母I前缀,以指示该类型为接口。令在定义类/接口对(其中类是接口的标准实现)时使用相似的名称。两个名称的区别应该只是接口名称上有字母I前缀。令不要使用下划线字符(_)。以下是正确命名的接口的示例。publicinterfaceIServiceProviderpublicinterfaceIFormatable以下代码示例阐释如何定义!Component接口及其标准实现Component类。publicinterface!Component()pu
23、blicclassComponent:!Component(/Implementationcodegoeshere.)2.2.10 属性命名指南应该总是将后缀AttribUte添加到自定义属性类。以下是正确命名的属性类的示例。publicclassObsoIeteAttributeO2.2.11 枚举类型命名指南枚举(Enum)值类型从Enum类继承。以下规则概述枚举的命名指南:令对于Enum类型和值名称使用Pascal大小写。令少用缩写。令不要在Enum类型名称上使用Enum后缀。令对大多数Enum类型使用单数名称,但是对作为位域的Enum类型使用复数名称。令总是将FlagsAttribut
24、e添加到位域Enum类型。2.2.12 静态字段命名指南以下规则概述静态字段的命名指南:令使用名词、名词短语或者名词的缩写命名静态字段。令使用Pascal大小写。令对静态字段名称使用匈牙利语表示法前缀。令建议尽可能使用静态属性而不是公共静态字段。2.2.13 参数命名指南以下规则概述参数的命名指南:令使用描述性参数名称。参数名称应当具有足够的描述性,以便参数的名称及其类型可用于在大多数情况下确定它的含义。令对参数名称使用Camel大小写。令使用描述参数的含义的名称,而不要使用描述参数的类型的名称。开辟工具将提供有关参数的类型的故意义的信息。因此,通过描述意义,可以更好地使用参数的名称。少用基于
25、类型的参数名称,仅在适合使用它们的地方使用它们。令不要使用保留的参数。保留的参数是专用参数,如果需要,可以在未来的版本中公开它们。相反,如果在类库的未来版本中需要更多的数据,请为方法添加新的重载。令不要给参数名称加匈牙利语类型表示法的前缀。以下是正确命名的参数的示例。TypeGetType(StringtypeName)stringFormat(stringformat,args()Asobject)2.2.14 方法命名指南以下规则概述方法的命名指南:令使用动词或者动词短语命名方法。令使用Pascal大小写。以下是正确命名的方法的实例。RemoveAll()GetCharArrayOInvo
26、keO2.2.15 属性命名指南以下规则概述属性的命名指南:令使用名词或者名词短语命名属性。令使用Pascal大小写令不要使用匈牙利语表示法。令考虑用与属性的基础类型相同的名称创建属性。例如,如果声明名为Color的属性,则属性的类型同样应该是Color0请参阅本主题中后面的示例。以下代码示例阐释正确的属性命名。publicclassSampleClass(publicColorBackColor(/CodeforGetandSetaccessorsgoeshere.以下代码示例阐释提供其名称与类型相同的属性。publicenumColor/InsertcodeforEnumhere.publ
27、icclassControlpublicColorColor(get/Insertcodehere.set/Insertcodehere.)以下代码示例不正确,原因是Color属性是Integer类型的。publicenumColor/InsertcodeforEnumhere.publicclassControl(publicintColor(get/Insertcodehere.)set/Insertcodehere.)在不正确的示例中,不可能引用Color枚举的成员。Color.Xxx将被解释为访问一个成员,该成员首先获取Color属性(在VisualBasic中为Integer类型,在
28、C#中为int类型)的值,然后再访问该值的某个成员(该成员必须是System.Int32的实例成员)。2216事件命名指南以下规则概述事件的命名指南:令对事件处理程序名称使用EventHandler后缀。令指定两个名为sender和e的参数。sender参数表示引起事件的对象。sender参数始终是object类型的,即使在可以使用更为特定的类型时也如此。与事件相关联的状态封装在名为e的事件类的实例中。对e参数类型使用适当而特定的事件类。令用EventArgs后缀命名事件参数类。令考虑用动词命名事件。令使用动名词(动词的“ing”形式)创建表示事件前的概念的事件名称,用过去式表示事件后。例如,
29、可以取销的Close事件应当具有Closing事件和CIOSed事件。不要使用BeforeXxx/AfterXxx命名模式。令不要在类型的事件声明上使用前缀或者后缀。例如,使用Close,而不要使用OnCloseo通常情况下,对于可以在派生类中重写的事件,应在类型上提供一个受保护的方法(称为OnXXX)。此方法只应具有事件参数e,因为发送方总是类型的实例。以下示例阐释具有适当名称和参数的事件处理程序。publicdelegatevoidMoUSeEVentHandlbjectsender,MouseEventArgse);以下示例阐释正确命名的事件参数类。publicclassMouseEve
30、ntArgs:EventArgs(intx;inty;ublicMouseEventArgs(intx,inty)this,x=x;this,y=y;publicintXgetreturnx;ublicintYgetreturny;2.3 注释(Comment)规范注释规范包括:模块(类)注释规范、类的属性、方法注释规范、代码间注释2.3.1 模块(类)注释规范模块开始必须以以下形式书写模块注释:/模块编号:模块编号,可以引用系统设计中的模块编号/作用:/如果模块有修改,则每次修改必须添加以下注释:/Log编号:/修改描述:对此修改的描述/作者:修改者中文名/修改日期:模块修改Fl期,格式:Y
31、YYY三-DD/2.3.2 类属性注释规范在类的属性必须以以下格式编写属性注释:/属性说明/2.3.3 方法注释规范在类的方法声明前必须以以下格式编写注释III/说明:对该方法的说明III/paramname=”参数说明X/paramIII/对方法返回值的说明,该说明必须明确说明返回的值代表什么含义/2.3.4 代码间注释规范代码间注释分为单行注释和多行注释:单行注释:/多行注释:/*多行注释1多行注释2多行注释3*/代码中遇到语句块时必须添加注释(if,for,foreach,,添加的注释必须能够说明此语句块的作用和实现手段(所用算法等等)。3成功的模式作为一个软件开辟者,在你的所有品中含有
32、一份有关标准的文档并不会自动地使你更加地有效率。要成功,你必须选择变得更有效率,这意味着你必须将这些标准有效地应用起来。3.1有效地使用这些标准以下的建议将匡助你更有效地使用本文所描述的c#编程标准和指南:1.理解标准。花些时间去理解为什么每一个标准和指南会使开辟效率提高。比如说,不要仅仅是因为指南中要求你才在一行仅声明一个局部变量,而应该是因为你明白它能使你的代码更易懂你才这样做。2信任这些标准。理解每一个标准是一个开始,但你还需要信任这些标准。遵守标准不应仅仅是当你有时间才做的事,而你应该向来遵守,因为你相信这是最好的程序设计方法。3 .当你写代码时就应该遵守标准,而不应是一个事后的想法。
33、加了注释的代码不仅在你写程序时,而且在你写完程序时,都更容易理解。在程序开辟阶段和维护阶段,一致性地命名成员函数和字段都使工作更加容易。在开辟和维护阶段,整洁的代码让工作更加容易。概括起来说,遵守标准将提高你开辟过程中的生产率,并且使你的代码更易维护(因此也使维护者的生产率提高了)。如果从一开始你就写出整洁的代码,你将在撰写过程中受益。4 .使它们成为你的质量保证的过程。代码检查的一部份应该是确保源码遵守你的机构所采用的标准。将标准作为你训练和指导开辟员更有效率的基础。3.2其它导向成功代码的因素1 .面向人而不是面向机器编程。你的开辟努力的主要目的应该是你的代码易被其它人理解。如果没人能理解
34、它,它就一点儿优点也没有。使用命名约定。注释代码。给代码分段。2 .首先设计,然后编写代码。你是否曾经遇到过这样的情况:一些你的程序所倚靠的代码需要修改?可能是要传一个新的参数给一个成员函数,或者是需要将一个类拆成几个类。为了确信你的代码与被重新设置修改的代码还能一起工作,你必须做多大的额外工作呢?你有多么乐意?你是否曾经问过自己,为什么有些人在开始写代码时不先停下来考虑一下,以避免这一切的发生?他们为什么不首先设计程用呢?固然你做了。如果你在实际开始动手写代码之前花时间想清晰你打算怎样写你的代码,你很可能可以少花些时间编写它。此外,仅通过开始时就将它们想好,你将潜在地减少将来修改代码所带来的
35、影响。3 .一小步一小步地开辟。一小步一小步地开辟,先写几个成员函数,检测它们,再多写几个,这样开辟比一次性地写完所有代码然后修改它要有效得多。检测和修改十行代码远比检修一百行代码要容易得多。实际上可以很有把握地说,同样是编写、测试和修改100行代码,十行十行地做所花的时间少于一口气做100行所花的时间的一半。理由很简单。当测试你的代码并发现问题时,问题几乎总是在刚写完的新代码中,固然这假定在剩下的那些旧代码上开始写是很可靠的。在一小部份代码中寻觅问题会比在一大段代码中找问题要快得多。通过一小步一小步逐步地开辟,减少了查找错误所需的平均时间,这转而又减少了整个的开辟时间。4 .让代码简洁。复杂
36、的代码兴许让人在智力上获得满足,但是如果别人读不懂,那就不好了。如果要求某人,甚至是你,第一次修改一段复杂的代码以纠正其中的错误或者对它进行增强,那末很可能代码会被重写。实际上,你很可能已经因为代码难懂而重写过别人的代码。当你在重写代码时,你是怎样认为代码的最初开辟者的呢?你认为那个人是天才还是怪物?写出那种后来要被重写的代码没什么可骄傲的,所以应该遵循KlSS法则:要使代码简单直白。5 .学习常用的模式、反模式和代码模式。有大量的分析、设计和处理的模式和反模式以及编程代码模式供你提高开辟效率。你的开辟工作的主要目的应该是你的代码易被其它人理解。如果没人能理解它,它就一点优点也没有。使用命名约定。注释代码。给它分段。