C#代码规范范本.docx

上传人:b****5 文档编号:8481896 上传时间:2023-01-31 格式:DOCX 页数:21 大小:27.46KB
下载 相关 举报
C#代码规范范本.docx_第1页
第1页 / 共21页
C#代码规范范本.docx_第2页
第2页 / 共21页
C#代码规范范本.docx_第3页
第3页 / 共21页
C#代码规范范本.docx_第4页
第4页 / 共21页
C#代码规范范本.docx_第5页
第5页 / 共21页
点击查看更多>>
下载资源
资源描述

C#代码规范范本.docx

《C#代码规范范本.docx》由会员分享,可在线阅读,更多相关《C#代码规范范本.docx(21页珍藏版)》请在冰豆网上搜索。

C#代码规范范本.docx

C#代码规范范本

C#编码规范

 

目录方针

该代码标准提供了相关软件开发项目中,使用C#进行编码时的规则,推荐代码标准,起到了一定的指示作用。

为了使该标准制定的方针浅显易懂,用了简单的代码来编写。

而在实际的编程中,是需要项目小组所有成员同意该编写规则的。

对于实际项目,我们推荐将该标准以顾客为标准使用。

还有,我们还推荐读者参考配合.NETFrameworkSDK帮助的《面向对象开发设计指南》。

※特别是在ExtremeProgramming项目中没有认识到的,可使用其它C#编程的项目中运用。

1.代码注释规范

(1)文件功能,创建,修改信息注释

(2)类功能注释

(3)方法注释

(4)较长的注释,*GY

需要复数行注释的情况下,在最初用短小的篇章写上想要注释什么。

然后在添加上长的注释。

另外,在感觉有必要写象如此长的注释之时,请再三考虑一下,可否将程序设计再简化一下。

请积极地应对。

2.目录文件构成

(5)目录文件名

Public类会生成一个以该类命名的文件。

例:

publicclassCustomer里面有着Customer.cs。

包内的非公共类,最好放在包含该类经常被使用的公共类目录文件下。

对于特殊类,一个目录文件可以包含多个类。

(6)目录文件的位置

决定了项目的根目录之后,在命名空间的“.”处输入导入目录的阶层位置。

可是对应于solution/project的命名空间的阶层则用solution名/project名作为目录名来使用。

例:

命名空间:

CompanyName.OrganizationName.TechnologyName.CoreFeatureName.SubFeatureName

SolutionSolutionName所对应的命名空间:

TechnologyName

ProjectProjectName所对应的命名空间:

CoreFeatureName

配置路径:

C:

\CompanyName\OrganizationName\SolutionName\ProjectName\SubFeatureName

(7)TestClass名

类ClassName的单元测试类是以ClassNameTest来命名的。

Solution的每个测试都是以SolutionNameTests来命名的。

例:

如果是Customer类的测试类的话就命名为CustomerTest.cs。

例:

如果是CsSample的soultion的话,就把它命名为CsSampleTests.csproj。

理由:

因为是这样命名是非常有一致性。

可以成为使用测试代码的样例和演示版。

(8)TestClass的位置

测试类的位置应配置在被测试类相同的阶层的目录下。

例:

被测试类的位置:

测试类的位置:

理由:

如果不是物理位置较近的话,会被维护系统所遗漏。

对于产品的代码分离这一点而言,用其他的工具(NAnt的build文件之类)也是可能调整的。

3.命名规则

(9)NameSpace结构规范

NameSpace分类和命名原则

先根据解决方案(Solution)、业务系统(Application)、子系统(Sub)、模块(Module)划分目录,然后在模块内部按照Web、Biz、integration层对NameSpace结构进行命名。

Web层NameSpace命名规范

●Beyondbit.Solution.Application.Sub.Module.Web

业务层NameSpace命名规范

●Beyondbit.Solution.Application.Sub.Module.Biz

数据访问层NameSpace命名规范

●Beyondbit.Solution.Application.Sub.Data

集成层NameSpace命名规范

●Beyondbit.Solution.Application.Sub.Module.Biz

Common

该目录应用于解决方案(Solution)、业务系统(application)、子系统(sub),存放在一些与业务相关的通用处理程序,可以视为公共的模块,可包含Web、Biz、integration。

Util

该目录应用于解决方案(Solution)、业务系统(Application)、子系统(Sub),存放在一些与业务无关的通用处理程序。

(10)文件名

Public类的命名一定要与文件名同名(包括大,小写的区别)。

(11)类名

类名使用Pascal大小写形式。

(12)异常类名

最后以Exception结尾。

(13)接口名

与类名相同。

此外,经常在最前面添加I。

interfaceIClassName

此外,在使用添加了某项功能的情况下,我们要加上可以表示这种功能的形容词,以-able结尾。

例:

IEnumerable,ICloneable,IXmlSerializable,…

(14)抽象类名

如果没有适合抽象类名的名字的时候,就联想以Abstract为开头的Subclass名作为抽象类的名字。

abstractclassAbstractBeforeSubClassName

(15)常量(Const)

用大写或者大写后加“_”。

constintUPPERCASE=0;

constintUPPERCASE_WITH_UNDERSCORES=0;

(16)枚举型(enum)

枚举名使用Pascal大小写格式。

enumPascalCasing

枚举型在表示位域的时候用复数。

并附加FlagsAttribute。

[Flags]enumPascalCasings

(17)枚举值

枚举值使用Pascal大小写格式。

PascalCasing

(18)事件名

事件名使用Pascal大小写格式。

eventPascalCasing()

(19)方法名

方法名使用Pascal大小写格式。

voidPascalCasing()

objectPascalCasing()

(20)factory方法(生成新的对象)

XNewX()

XCreateX()

(21)转换方法(把一个对象转换成别的对象)

XToX()

(22)属性名

属性名使用Pascal大小写形式。

objectPascalCasing

(23)Boolean变量返回方法

Is+形容词、Can+动词、Has+过去分词、三单元名词、三单元动词+名詞。

好的例子:

boolIsEmpty()

boolCanGet()

boolHasChanged()

boolContains(objectx)

boolContainsKey(stringkey)

boolCheckUserRight(stringuserId,stringrightId)

不好的例子:

boolEmpty()//方法调用者会理解成“清空”的意思。

理由:

方法调用者很容易理解if,while等条件语句的条件。

另外,也很容易理解ture意味着什么。

(24)Bool变量

形容词、is+形容词、can+动词、has+过去分词、三单元动词、三单元动词+名词。

形容詞、is+形容詞、can+動詞、has+過去分詞、三単元動詞、三単元動詞+名詞。

boolisEmpty;

booldirty;

boolcontainsMoreElements;

(25)英语和中文

所有的关键词名都是以英语为基础,另外,在整个项目的制作周期中都有中英对照字典的支持。

(26)命名的对称性

要取类名,方法名的时候请注意以下的英语的对称性。

Add/Remove

Insert/Delete

Get/Set

Start/Stop

Begin/End

Send/Receive

First/Last

Get/Release

Put/Get

Up/Down

Show/Hide

Source/Target

Open/Close

Source/Destination

Increment/Decrement

Lock/Unlock

Old/New

Next/Previous

(27)循环计数器

对于应用Scope(适用范围)的局部循环计数器,以i,j,k为顺序依次命名。

(28)Scope的局部变量命名

Scope的局部变量名最好使用其类型名的缩写。

例:

DataSetds=newDataSet();

(29)有意义的命名

最好使用从名字中就可以看出其变量作用的变量名。

不好的例子:

Copy(strings1,strings2)

好的例子:

Copy(stringsource,stringdestination)

(30)无意义的命名

用Info,Data,Temp,Str,Buf这些做变量名的时候需要再三考虑。

不好的例子:

doubletemp=Math.Sqrt(b*b-4*a*c);

好的例子:

doubledeterminant=Math.Sqrt(b*b-4*a*c);

(31)private/protected/internal/protectedinternalscope的实例变量

使用Camel大小写形式。

我们需要考虑的是使变量更加容易读懂。

privateobjectcamelCasing;

protectedobjectcamelCasing;

internalobjectcamelCasing;

protectedinternalobjectcamelCasing;

(32)publicscope的实例变量

使用Pascal大小写形式。

开头用大写。

publicobjectPascalCasing;

(33)private/protected/internal/protectedinternalscoope的公共变量

使用Camel大小写形式。

我们要考虑使得变量更加容易读懂。

privatestaticobjectcamelCasing;

protectedstaticobjectcamelCasing;

internalstaticobjectcamelCasing;

protectedinternalstaticobjectcamelCasing;

(34)publicscope的公共变量

使用Pascal大小写形式。

publicstaticobjectPascalCasing;

(35)Local变量

使用Camel大小写形式。

objectcamelCasing;

(36)大写与小写

大写与小写被作为不同的文字被使用。

仅仅因为这个区别我们就不得不注意名字的取法。

4.代码编写

(37)#Region/#EndRegiondirective

代码域要声明#Region/#EndRegiondirective,要包含这个域相关的说明。

例:

#Region"实例变量"

privatestringname;

#EndRegion

#Region"Constract"

publicMyClass(stringname)

{

this.name=name;

}

#EndRegion

(38)声明方法/属性

声明方法/属性要明确指出scope。

(39)较长的行

一行最多100位,如果有超过的情况要分割行。

分行指针通过逗号另起一行。

例:

doublelength=Math.Sqrt(Math.Pow(newRandom().NextDouble(),2.0)+Math.Pow(newRandom().NextDouble(),2.0));

doublelength=Math.Sqrt(Math.Pow(newRandom().NextDouble(),2.0),

Math.Pow(newRandom().NextDouble(),2.0));

(40)较长的类的声明

类声明较长的情况下,请换成多行。

例:

publicclassLongNameClassImplemenation:

AbstractImplementation,IXmlSerializable,Icloneable

那么请变为:

publicclassLongNameClassImplemenation:

AbstractImplementation,

IXmlSerializable,ICloneable

(41)较长的方法声明

方法声明较长的情况下,请换成多行。

例:

publicvoidLongMethodSignature(inta,intb,intc,

intd,inte,intf)

(42)abstractClassvs.interface

请尽量不要使用抽象类(abstractclass),多使用interface。

abstractclass是有体方法与抽象方法的结合使用。

理由:

一个类可以实现很多接口,却只能继承一个抽象类。

一个类继承之抽象类后就不能继承其他的类,会造成浪费。

(43)publicVariable

类变量请不要频繁将其设为public的作用域,请将它设置为合适的作用域。

理由:

这是面向对象的标准。

随意地访问类的内部状态是不好的。

可是,在满足以下全部条件时,类的public变量可以直接访问。

●该类变量独立于其他的类变量,单独变更其内容的话,是不会对内部的整合性造成影响的。

●无论哪个,都要编写上get/set访问。

●有证据说明类变量在实例化后不会变更。

另外,遇到不适合上述情况的时候,如需要极度注重开发速度的情况。

也不仅限于上述的标准。

(可是,需要我们慎重地注释)

(44)初始化

不要指望默认的初始化(比如将某些变量用null值初始化之类)。

另外,不要再次初始化。

不好的例子:

publicclassPoorInitialization

{

privatestringname="initial_name";

publicPoorInitialization()

{

name="initial_name";

}

}

理由:

请把关于初始化的Bug减到最低。

(45)避免static变量

请尽力避免static变量。

理由:

它使用了更加使上下文连贯的代码,覆盖隐藏了副作用。

(46)privatevs.protected

比起private,我们应更多使用protected。

理由:

private不让该类以外的其他类调用。

客户无法对继承此类的private的方法重新实现。

别的方法:

请选private使用。

如果将属性变为protected之后,如果该类有变更的话,那么对全部继承它的类都会有影响。

(47)get/set访问

请避免随便地将实例变量的作用域(get/set访问)定为public的作用域。

在这之前请讨论其必要性,将它做成更加有意义的属性/方法。

理由:

类变量经常依赖其他类变量。

我们不能破坏类内部的整合性。

(48)隐藏变量

隐藏变量名请避免和基本类中的变量名同名。

理由:

一般来说,会产生Bug。

如果有特殊意义的话请注释一下。

(49)Public方法

类的public方法是以“自动贩卖机的界面”为目标,为了变得浅显易懂,即使使用方法错误,也不会破坏其内部整合性而设计的。

另外,如果可能的话,请根据协议而设计(DesignbyContract),与类的不变条件一起,用代码表现方法的重载。

(50)获得状态与变更状态的分离

请将方法设计为执行“一种功能”。

特别是,变更状态和获得状态这两种服务不能在一个方法内执行。

请用void做为状态变更方法的返回值。

理由1:

只执行一件事情的方法比较容易理解。

理由2:

比较容易做到对于并发性的控制,异常的安全保证。

理由3:

根据子类化比较容易扩展。

(51)this的返回

就算是为了客户的方便着想,也请尽量避免this的返回。

理由:

像A.Meth1().Meth2().Meth3()这样的连锁,一般会变成Synchronization上问题的根源。

(52)方法的多重定义

根据参数的类型不同,请尽量避免方法的重载(如果参数不相同的话是可以)。

特别是,如果和继承挂钩的话会很麻烦。

例:

错误:

overridevoidDraw(Rectanglerectangle)

overridevoidDraw(Pointpoint)

正确:

voidDrawRectangle(Rectanglerectangle)

voidDrawPoint(Pointpoint)

(53)Equals()与GetHashCode()

如果要重载Object.Equals()方法的话,请同时重载GetHashCode()方法。

相反也一样。

理由:

为了对应容器类(Hashtable)

(54)Clone()

如果,使用了Clone()方法的话,实际装载ICloneable明确地书写。

例:

usingSystem;

publicclassFoo:

ICloneable

{

publicobjectICloneable.Clone()

{

FoomyFoo=(Foo)this.Clone();

//Foo类属性的clone

//...

}

}

理由:

有许多例子表明简易的复制是不好的。

(55)deflautconstract

如果可能的话,请都准备使用一个deflautconstract(哪怕是没有参数)。

理由:

使用reflection,用Assembly.CreateInstance(TypeName)从类型名字符串开始做成该动态类。

(56)abstractMethodinabstractclasses

对于abstract类来说,比起书写no-op的方法来,请明确地声明成abstract方法。

另外,如果可以准备好可能共享的default的实现的话,将其设为protected属性,请在子类中用一行书写处理方法。

理由:

.NET的IDE并没有实际实现。

为了检测出abstract方法,可以回避仅仅忘记实际实现IDE的BUG。

(57)类型的变换

类型的变换请使用Convert类。

stringstr="123456789";

intnum=Convert.ToInt32(str);

intnum=123456789;

stringstr=Convert.ToString(num);

(58)对象的同值比较

对象比较==使用方法,不使用Equals。

String的比较就使用==来比较。

另外,比较独立对象的情况下,请按照如下的方式来实现独立对象:

Equals,GetHashCode,operator==,operator!

=

理由:

如果使用Equals方法的话,源代码就会看上去比较混乱。

classHoge

{

privatestrings;

publicHoge(strings)

{

this.s=s;

}

publicoverrideboolEquals(Objecta)

{

returnEquals(this.s,((Hoge)a).s);

}

publicstaticbooloperator==(Hogea,Hogeb)

{

returnEquals(a.s,b.s);

}

publicstaticbooloperator!

=(Hogea,Hogeb)

{

return!

Equals(a.s,b.s);

}

publicoverrideintGetHashCode()

{

returns.GetHashCode();

}

}

(59)声明与初始化

Local变量请和初始值一起声明。

理由:

请最小化关于变量值的设定。

不好的例子:

voidf(intstart)

{

inti,j;//没有声明初始值

//许多代码

//...

i=start+1;

j=i+1;

//使用了i,j

//...

}

好的例子:

voidf(intstart)

{

//许多代码

//...

inti=start+1;

intj=i+1;

//使用了i,j

//...

}

(60)Local变量重复使用的坏处

如果重复使用Local变量,应该声明新的变量并初始化。

理由:

关于变量值的假定应该最小化。

理由:

对编译的优化有帮助。

不好的例子:

voidf(intn,intdelta)

{

inti;//没有初始化的声明

for(i=0;i

{

//使用了i

}

for(i=0;i

{

if(...)

{

break;

}

}

if(i!

=n-1)//循环终止判定条件里面使用了i

{

//...

}

i=n-delta*2;//再次使用了i

//...

}

好的例子:

voidf(intn,intdelta)

{

  for(inti=0;i

{

  //使用了i

  }

boolfound=false;

for(intj=0;i

{

//使用了j

if(...)

{

found=true;

break;

}

}

if(found)

{

//...

}

inttotal=n-delta*2;//有着其他意思的变量

  //...

}

(61)大小比较运算符

比较习惯使用“<”、“<=”,而“>”、“>=”请尽量避免。

理由:

为了统一字符大小的方向,右边的字符大的话,可以避免混乱。

(62)If/while条件中的“=”

对于if,while的条件,不可以代入“=”使用。

理由:

几乎在所有这

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 工学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1