词语选择
避免使用由经常使用的名称空间复制的类型名。类型名不能使用下列词语。
system collections forms ui
避免使用与常用关键词冲突的标识符。例如,避免使用下列词语。
标识符(包括参数名)中不要使用缩写。
如果必须使用缩写:
任何超过两个字符以上的缩写都使用camel大写格式,即使这不是标准缩写。
名称空间
命名名称空间的一般规则如下:
companyname.technologyname
这样,我们看到的名称空间应该是这样的:
microsoft.office
powersoft.powerbuilder
注意:这只是一个原则。第三方公司可以选择其它的名字。
避免用公司名称或其它著名品牌的名称作为名称空间的前缀,这样会造成两个公布的名称空间有同一个名称的可能性。(例如,将微软提供的office自动类命名为microsoft.office。)
使用pascal大写方式,用逗号分隔逻辑成分(例如,microsoft.office.powerpoint)。如果你的品牌使用的是非传统大写方式,那么一定要遵循你的品牌所确定使用的大写方式,即使这种方式背离了通常的名称空间大写规则(例如,next.webobjects,和ee.cummings。)
该用复数的时候要使用复数的名称空间名。例如,使用system.collections而不是system.collection。本规则的特例是品牌名称和缩写。例如:使用system.io而不是system.ios。
名称空间和类不能使用同样的名字。例如,有一个类被命名为debug后,就不要再使用debug作为一个名称空间名。
类和类成分
类的命名原则
用名词或名词短语命名类。
使用pascal大写。
减少类名中缩写的使用量。
不要使用任何类前缀(比如c)。
不要使用带下划线的字符。
下面是一些正确命名的类名的例子。
public class filestream {
}
public class button {
}
public class string {
}
接口命名原则
使用名词或名词短语,或者描述行为的形容词来命名接口。例如,icomponent(描述性名词),icustomattributeprovider(名词短语),和ipersistable(形容词)。
使用pascal大写。
减少接口名中缩写的使用量。
不要使用带下划线的字符。
在接口名前加前缀i,以表示这个类型是一个接口。
不要在类名前加上前缀c。偶而情况下,需要在类名前加上i而并不表示它是一个接口。在这种情况下,只要i后面的字符是小写就可(例如,identitystore。)
当类是接口的标准执行时,定义这一对类/接口组合就要使用相似的名称。两个名称的不同之处只是接口名前有一个i前缀。
下面我们举个例子,来看看接口icomponent和它的标准执行,类component。
public interface icomponent {
}
public class component : icomponent {
}
public interface iserviceprovider{
}
public interface iformatable {
}
属性命名原则
在属性的后面加上attribute后缀,来自定义属性类。如下例所示。
public class obsoleteattribute{
}
enum命名原则
enum需使用pascal大写。
enum值名需使用pascal大写。
减少enum名中缩写的使用量。
enum名前不要加前缀(例如,adxxx表示ado enums,rtfxxx表示多信息文本enum,等等。)。
在enum类型上不要加enum后缀。
enum名称需使用单数名词。
比特域使用复数名词。
如果列举值在参数或属性中使用,需用一个enum来定义列举值。这样工具就可以知道一个属性或参数可能的值了。
public enum filemode{
create,
createnew,
open,
openorcreate,
truncate
}
如果数字值to be bitwise ored together,就使用flags对属性进行自定义。
[flags]
public enum bindings {
createinstance,
defaultbinding,
excatbinding,
getfield,
getproperty,
ignorecase,
invokemethod,
nonpublic,
oabinding,
setfield
setproperty,
static
}
在封装一个win32 api时,这个规则有一个特例。从一个win32标头产生内部定义是很常见的。你可以使用win32大写,这种形式下字母通常全部大写。
使用int32作为一个enum的基础类型。
如果这个enum代表标志,而且标志又非常多(大于32),或者这个enum在将来可以发展成许多标志,或者类型需要与类型int有所不同以便向后兼容时,在这种情况下就产生了特例。
只有在值可以被完全表示为一组位标志时,才使用enum。开集不能使用enum(例如操作系统版,等等)。
只读和const字段名
用名词,名词短语,或名词的缩写命名静态字段。
用pascal大写命名静态字段。
不要用匈牙利文类型的符号作静态字段名的前缀。
参数名
使用描述性参数名。参数名应该具有足够的描述性,这样在大多数情况下参数名和它的种类可以用来确定它的意思。
用camel大写方式命名参数。
根据参数的意思来命名参数,而不是根据参数的种类来命名。我们希望开发工具可以用很方便的方式提供关于参数种类的信息,这样参数名可以得到更好的使用,可以对语义而不是对种类进行描述。但是偶尔使用根据类型命名的参数名也是完全可以的。
不要使用保留参数。如果在下一个版本中需要更多的数据,可以增加进来。
不要用匈牙利文类型的符号作为字段名的前缀。
type gettype (string typename)
string format (string format, object [] args)
方法命名原则
用动词或动词短语命名方法。
用下述范例所示的pascal大写方式命名方法。
removeall()
getchararray()
invoke()
属性命名原则
用名词或名词短语命名属性。
用pascal大写命名属性。
属性与类型要一样。
用与一个类型的名称相同的名字来命名属性时,就使这个属性的类型成为那个类型。虽然听起来有些奇怪,但这是正确的。下面的例子正确使用了属性命名原则。
public enum color {...}
public class control {
public color color { get {...} set {...} }
}
下例就是不正确的。
public enum color {...}
public class control {
public int color { get {...} set {...} }
}
在那个不正确的例子中,要想引用color enum是不可能的,因为color,xxx会被翻译成一个成员访问,它会首先获得color属性的值(int种类),然后再访问那个值的成员(它应该是system.int32的一个实例成员)。
事件命名原则
用eventhandloer后缀命名事件处理程序,如下列所示。
public delegate void mouseeventhandler(object sender, mouseevent e);
使用名为sender和e的两个参数。
sender参数代表提出事件的对象。sender参数永远是一个类型对象,即使它可能使用了更为特定的类型。
与事件相关的状态被封装在一个名为e的事件类范例中。要使用这个类型的正确的、特定的事件类。
public delegate void mouseeventhandler(object sender, mouseevente);
用eventargs后缀命名事件自变量类,如下例所示。
public class mouseeventargs : eventargs {
int x;
int y;
public mouseeventargs(int x, int y)
{ this.x = x; this.y = y; }
public int x { get { return x; } }
public int y { get { return y; } }
}
命名事件名时,需要有之前和之后的时态概念,因此要使用现在时态和过去时态(不要使用beforexxx\afterxxx的方式)。例如,可以被取消的结束事件就有closing事件和closed事件。
public event controleventhandler controladded {
//..
}
用动词命名事件。
区分大小写
不要使用需要对大小写作出区分的名称。各成分不论是在区分大小写还是不区分大小写的语言下都必须是完全可用的。因为不区分大小写的语言不能在同样的环境下对只有大小写不同的两个名称作出辩别,所以成分必须避免这种情况。
不要产生两个名称相同只有大小写不同的名称空间。
namespace ee.cummings;
namespace ee.cummings;
带有两个参数的一个类型,其两个参数的名称不能只有大小写不同。
void foo(string a, string a)
system.winforms.point p;
system.winforms.point pp;
带有两个属性的一个类型,其属性的名称不能只有大小写不同。
int foo {get, set};
int foo {get, set}
带有两种方法的一个类型,其方法的名称不能只有大小写不同。
void foo();
void foo();
避免类型名出现混淆
不同的语言使用不同的术语以识别基本管理类型。设计人员必须避免使用对语言有专门要求的术语。遵照本章说明的规则,避免出现类型名称混淆的情况。
使用语义上有意义的名称,而不要使用类型名称。
在很少见的情况下,参数除了类型以外语义上没有任何意义,这时使用类属名。例如,一个类支持将多种数据类型写进一个流中,这个类可能有下列方法:
void write(double value);
void write(float value);
void write(long value);
void write(int value);
void write(short value);
上面的例子在下述对语言有专门要求的情况下是首选。
void write(double doublevalue);
void write(float floatvalue);
void write(long longvalue);
void write(int intvalue);
void write(short shortvalue);
在极端情况下,每一个基本数据类型需要有唯一的命名方式,此时使用下面的通用类型名称。
一个支持从流中读取多种数据类型的类可以有下列方法。
double readdouble();
float readsingle();
long readin64();
int readint32();
short readint16();
上面的例子在下述对语言有专门要求的情况下是首选。
double readdouble();
float readfloat();
long readlong();
int readint();
short readshort();
避免使用由经常使用的名称空间复制的类型名。类型名不能使用下列词语。
system collections forms ui
避免使用与常用关键词冲突的标识符。例如,避免使用下列词语。
addhandler | addressof | alias | and | ansi |
as | assembly | auto | bitand | bitnot |
bitor | bitxor | boolean | byref | byte |
byval | call | case | catch | cbool |
cbyte | cchar | cdate | cdec | cdbl |
char | cint | class | clng | cobj |
const | cshort | csng | cstr | ctype |
date | decimal | declare | default | delegate |
dim | do | double | each | else |
elseif | end | enum | erase | error |
event | exit | externalsource | false | finally |
for | friend | function | get | gettype |
goto | handles | if | implements | imports |
in | inherits | integer | interface | is |
let | lib | like | long | loop |
me | mod | module | mustinherit | mustoverride |
mybase | myclass | namespace | new | next |
not | nothing | notinheritable | notoverridable | object |
on | option | optional | or | overloads |
overridable | overrides | paramarray | preserve | private |
property | protected | public | raiseevent | readonly |
redim | region | rem | removehandler | resume |
return | select | set | shadows | shared |
short | single | static | step | stop |
string | structure | sub | synclock | then |
throw | to | true | try | typeof |
unicode | until | variant | when | while |
with | withevents | writeonly | xor | eval |
extends | instanceof | package | var |
标识符(包括参数名)中不要使用缩写。
如果必须使用缩写:
任何超过两个字符以上的缩写都使用camel大写格式,即使这不是标准缩写。
名称空间
命名名称空间的一般规则如下:
companyname.technologyname
这样,我们看到的名称空间应该是这样的:
microsoft.office
powersoft.powerbuilder
注意:这只是一个原则。第三方公司可以选择其它的名字。
避免用公司名称或其它著名品牌的名称作为名称空间的前缀,这样会造成两个公布的名称空间有同一个名称的可能性。(例如,将微软提供的office自动类命名为microsoft.office。)
使用pascal大写方式,用逗号分隔逻辑成分(例如,microsoft.office.powerpoint)。如果你的品牌使用的是非传统大写方式,那么一定要遵循你的品牌所确定使用的大写方式,即使这种方式背离了通常的名称空间大写规则(例如,next.webobjects,和ee.cummings。)
该用复数的时候要使用复数的名称空间名。例如,使用system.collections而不是system.collection。本规则的特例是品牌名称和缩写。例如:使用system.io而不是system.ios。
名称空间和类不能使用同样的名字。例如,有一个类被命名为debug后,就不要再使用debug作为一个名称空间名。
类和类成分
类的命名原则
用名词或名词短语命名类。
使用pascal大写。
减少类名中缩写的使用量。
不要使用任何类前缀(比如c)。
不要使用带下划线的字符。
下面是一些正确命名的类名的例子。
public class filestream {
}
public class button {
}
public class string {
}
接口命名原则
使用名词或名词短语,或者描述行为的形容词来命名接口。例如,icomponent(描述性名词),icustomattributeprovider(名词短语),和ipersistable(形容词)。
使用pascal大写。
减少接口名中缩写的使用量。
不要使用带下划线的字符。
在接口名前加前缀i,以表示这个类型是一个接口。
不要在类名前加上前缀c。偶而情况下,需要在类名前加上i而并不表示它是一个接口。在这种情况下,只要i后面的字符是小写就可(例如,identitystore。)
当类是接口的标准执行时,定义这一对类/接口组合就要使用相似的名称。两个名称的不同之处只是接口名前有一个i前缀。
下面我们举个例子,来看看接口icomponent和它的标准执行,类component。
public interface icomponent {
}
public class component : icomponent {
}
public interface iserviceprovider{
}
public interface iformatable {
}
属性命名原则
在属性的后面加上attribute后缀,来自定义属性类。如下例所示。
public class obsoleteattribute{
}
enum命名原则
enum需使用pascal大写。
enum值名需使用pascal大写。
减少enum名中缩写的使用量。
enum名前不要加前缀(例如,adxxx表示ado enums,rtfxxx表示多信息文本enum,等等。)。
在enum类型上不要加enum后缀。
enum名称需使用单数名词。
比特域使用复数名词。
如果列举值在参数或属性中使用,需用一个enum来定义列举值。这样工具就可以知道一个属性或参数可能的值了。
public enum filemode{
create,
createnew,
open,
openorcreate,
truncate
}
如果数字值to be bitwise ored together,就使用flags对属性进行自定义。
[flags]
public enum bindings {
createinstance,
defaultbinding,
excatbinding,
getfield,
getproperty,
ignorecase,
invokemethod,
nonpublic,
oabinding,
setfield
setproperty,
static
}
在封装一个win32 api时,这个规则有一个特例。从一个win32标头产生内部定义是很常见的。你可以使用win32大写,这种形式下字母通常全部大写。
使用int32作为一个enum的基础类型。
如果这个enum代表标志,而且标志又非常多(大于32),或者这个enum在将来可以发展成许多标志,或者类型需要与类型int有所不同以便向后兼容时,在这种情况下就产生了特例。
只有在值可以被完全表示为一组位标志时,才使用enum。开集不能使用enum(例如操作系统版,等等)。
只读和const字段名
用名词,名词短语,或名词的缩写命名静态字段。
用pascal大写命名静态字段。
不要用匈牙利文类型的符号作静态字段名的前缀。
参数名
使用描述性参数名。参数名应该具有足够的描述性,这样在大多数情况下参数名和它的种类可以用来确定它的意思。
用camel大写方式命名参数。
根据参数的意思来命名参数,而不是根据参数的种类来命名。我们希望开发工具可以用很方便的方式提供关于参数种类的信息,这样参数名可以得到更好的使用,可以对语义而不是对种类进行描述。但是偶尔使用根据类型命名的参数名也是完全可以的。
不要使用保留参数。如果在下一个版本中需要更多的数据,可以增加进来。
不要用匈牙利文类型的符号作为字段名的前缀。
type gettype (string typename)
string format (string format, object [] args)
方法命名原则
用动词或动词短语命名方法。
用下述范例所示的pascal大写方式命名方法。
removeall()
getchararray()
invoke()
属性命名原则
用名词或名词短语命名属性。
用pascal大写命名属性。
属性与类型要一样。
用与一个类型的名称相同的名字来命名属性时,就使这个属性的类型成为那个类型。虽然听起来有些奇怪,但这是正确的。下面的例子正确使用了属性命名原则。
public enum color {...}
public class control {
public color color { get {...} set {...} }
}
下例就是不正确的。
public enum color {...}
public class control {
public int color { get {...} set {...} }
}
在那个不正确的例子中,要想引用color enum是不可能的,因为color,xxx会被翻译成一个成员访问,它会首先获得color属性的值(int种类),然后再访问那个值的成员(它应该是system.int32的一个实例成员)。
事件命名原则
用eventhandloer后缀命名事件处理程序,如下列所示。
public delegate void mouseeventhandler(object sender, mouseevent e);
使用名为sender和e的两个参数。
sender参数代表提出事件的对象。sender参数永远是一个类型对象,即使它可能使用了更为特定的类型。
与事件相关的状态被封装在一个名为e的事件类范例中。要使用这个类型的正确的、特定的事件类。
public delegate void mouseeventhandler(object sender, mouseevente);
用eventargs后缀命名事件自变量类,如下例所示。
public class mouseeventargs : eventargs {
int x;
int y;
public mouseeventargs(int x, int y)
{ this.x = x; this.y = y; }
public int x { get { return x; } }
public int y { get { return y; } }
}
命名事件名时,需要有之前和之后的时态概念,因此要使用现在时态和过去时态(不要使用beforexxx\afterxxx的方式)。例如,可以被取消的结束事件就有closing事件和closed事件。
public event controleventhandler controladded {
//..
}
用动词命名事件。
区分大小写
不要使用需要对大小写作出区分的名称。各成分不论是在区分大小写还是不区分大小写的语言下都必须是完全可用的。因为不区分大小写的语言不能在同样的环境下对只有大小写不同的两个名称作出辩别,所以成分必须避免这种情况。
不要产生两个名称相同只有大小写不同的名称空间。
namespace ee.cummings;
namespace ee.cummings;
带有两个参数的一个类型,其两个参数的名称不能只有大小写不同。
void foo(string a, string a)
system.winforms.point p;
system.winforms.point pp;
带有两个属性的一个类型,其属性的名称不能只有大小写不同。
int foo {get, set};
int foo {get, set}
带有两种方法的一个类型,其方法的名称不能只有大小写不同。
void foo();
void foo();
避免类型名出现混淆
不同的语言使用不同的术语以识别基本管理类型。设计人员必须避免使用对语言有专门要求的术语。遵照本章说明的规则,避免出现类型名称混淆的情况。
使用语义上有意义的名称,而不要使用类型名称。
在很少见的情况下,参数除了类型以外语义上没有任何意义,这时使用类属名。例如,一个类支持将多种数据类型写进一个流中,这个类可能有下列方法:
void write(double value);
void write(float value);
void write(long value);
void write(int value);
void write(short value);
上面的例子在下述对语言有专门要求的情况下是首选。
void write(double doublevalue);
void write(float floatvalue);
void write(long longvalue);
void write(int intvalue);
void write(short shortvalue);
在极端情况下,每一个基本数据类型需要有唯一的命名方式,此时使用下面的通用类型名称。
c# type name | visual basic type name | jscript type name | visual c++ type name | il representation | universal type name |
sbyte | sbyte | sbyte | char | i1 | sbyte |
byte | byte | byte | unsigned char | u1 | byte |
short | short | short | short | i2 | int16 |
ushort | uint16 | uint16 | unsigned short | u2 | uint16 |
int | integer | int | int | i4 | int32 |
uint | na | na | unsigned int | u4 | uint32 |
long | long | long | __int64 | i8 | int64 |
ulong | uint64 | uint64 | unsigned __int64 | u8 | uint64 |
float | single | float | float | r4 | single |
double | double | double | double | r8 | double |
bool | boolean | boolean | bool | i4 | boolean |
char | char | char | wchar_t | u2 | char |
string | string | string | string | system.string | string |
object | object | object | object | system.object | object |
一个支持从流中读取多种数据类型的类可以有下列方法。
double readdouble();
float readsingle();
long readin64();
int readint32();
short readint16();
上面的例子在下述对语言有专门要求的情况下是首选。
double readdouble();
float readfloat();
long readlong();
int readint();
short readshort();